diff --git a/doc/sqlmap-泛读报告.docx b/doc/sqlmap-泛读报告.docx
new file mode 100644
index 0000000..c87ed17
Binary files /dev/null and b/doc/sqlmap-泛读报告.docx differ
diff --git a/src/sqlmap-master/extra/beep/beep.py b/src/sqlmap-master/extra/beep/beep.py
index 788bafd..4ed4a29 100644
--- a/src/sqlmap-master/extra/beep/beep.py
+++ b/src/sqlmap-master/extra/beep/beep.py
@@ -9,96 +9,114 @@ See the file 'LICENSE' for copying permission
 
 import os
 import sys
-import wave
+import wave  # 用于处理 WAV 文件格式
 
+# 指定蜂鸣音频文件的路径
 BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
 
 def beep():
+    """根据操作系统播放蜂鸣声。"""
     try:
+        # 检测操作系统并调用相应的播放方法
         if sys.platform.startswith("win"):
-            _win_wav_play(BEEP_WAV_FILENAME)
+            _win_wav_play(BEEP_WAV_FILENAME)  # Windows 系统使用 WAV 播放
         elif sys.platform.startswith("darwin"):
-            _mac_beep()
+            _mac_beep()  # macOS 系统使用系统蜂鸣
         elif sys.platform.startswith("cygwin"):
-            _cygwin_beep(BEEP_WAV_FILENAME)
+            _cygwin_beep(BEEP_WAV_FILENAME)  # Cygwin 使用音频文件播放
         elif any(sys.platform.startswith(_) for _ in ("linux", "freebsd")):
-            _linux_wav_play(BEEP_WAV_FILENAME)
+            _linux_wav_play(BEEP_WAV_FILENAME)  # Linux 和 FreeBSD 系统使用 WAV 播放
         else:
-            _speaker_beep()
+            _speaker_beep()  # 其他系统使用控制台蜂鸣
     except:
+        # 捕获异常并使用控制台蜂鸣
         _speaker_beep()
 
 def _speaker_beep():
-    sys.stdout.write('\a')  # doesn't work on modern Linux systems
+    """在控制台播放蜂鸣声(警报声)。"""
+    sys.stdout.write('\a')  # 在现代 Linux 系统上可能无效
 
     try:
-        sys.stdout.flush()
+        sys.stdout.flush()  # 尝试刷新标准输出
     except IOError:
-        pass
+        pass  # 忽略任何 I/O 错误
 
-# Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html
+# Cygwin 使用系统命令播放音频文件
 def _cygwin_beep(filename):
     os.system("play-sound-file '%s' 2>/dev/null" % filename)
 
+# macOS 系统使用 Carbon 库的 SysBeep 函数
 def _mac_beep():
-    import Carbon.Snd
-    Carbon.Snd.SysBeep(1)
+    import Carbon.Snd  # 导入 Carbon 库
+    Carbon.Snd.SysBeep(1)  # 播放系统蜂鸣声
 
+# Windows 系统播放 WAV 文件
 def _win_wav_play(filename):
-    import winsound
+    import winsound  # 导入 winsound 库
 
-    winsound.PlaySound(filename, winsound.SND_FILENAME)
+    winsound.PlaySound(filename, winsound.SND_FILENAME)  # 播放指定的 WAV 文件
 
+# Linux 系统播放 WAV 文件的实现
 def _linux_wav_play(filename):
+    # 尝试使用不同的命令播放音频文件
     for _ in ("aplay", "paplay", "play"):
         if not os.system("%s '%s' 2>/dev/null" % (_, filename)):
-            return
+            return  # 成功播放音乐后返回
 
-    import ctypes
+    import ctypes  # 导入 ctypes 库以调用 C 函数
 
+    # PulseAudio 的相关常量定义
     PA_STREAM_PLAYBACK = 1
     PA_SAMPLE_S16LE = 3
-    BUFFSIZE = 1024
+    BUFFSIZE = 1024  # 缓冲区大小
 
+    # 定义 PulseAudio 样本规格的结构
     class struct_pa_sample_spec(ctypes.Structure):
         _fields_ = [("format", ctypes.c_int), ("rate", ctypes.c_uint32), ("channels", ctypes.c_uint8)]
 
     try:
-        pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")
+        pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")  # 加载 PulseAudio 库
     except OSError:
-        return
+        return  # 如果加载失败,则返回
 
+    # 打开 WAV 文件
     wave_file = wave.open(filename, "rb")
 
+    # 设置 PulseAudio 样本规格
     pa_sample_spec = struct_pa_sample_spec()
-    pa_sample_spec.rate = wave_file.getframerate()
-    pa_sample_spec.channels = wave_file.getnchannels()
-    pa_sample_spec.format = PA_SAMPLE_S16LE
+    pa_sample_spec.rate = wave_file.getframerate()  # 获取采样频率
+    pa_sample_spec.channels = wave_file.getnchannels()  # 获取声道数
+    pa_sample_spec.format = PA_SAMPLE_S16LE  # 设置样本格式
 
     error = ctypes.c_int(0)
 
-    pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error))
+    # 创建 PulseAudio 流
+    pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None,
+                                  "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error))
     if not pa_stream:
         raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error)))
 
     while True:
+        # 获取延迟
         latency = pa.pa_simple_get_latency(pa_stream, ctypes.byref(error))
         if latency == -1:
             raise Exception("Getting latency failed")
 
-        buf = wave_file.readframes(BUFFSIZE)
+        buf = wave_file.readframes(BUFFSIZE)  # 从 WAV 文件读取帧
         if not buf:
-            break
+            break  # 如果没有更多帧可读,退出循环
 
+        # 播放读取的帧
         if pa.pa_simple_write(pa_stream, buf, len(buf), ctypes.byref(error)):
             raise Exception("Could not play file")
 
-    wave_file.close()
+    wave_file.close()  # 关闭 WAV 文件
 
+    # 确保所有数据都已播放完成
     if pa.pa_simple_drain(pa_stream, ctypes.byref(error)):
         raise Exception("Could not simple drain")
 
-    pa.pa_simple_free(pa_stream)
+    pa.pa_simple_free(pa_stream)  # 释放 PulseAudio 流资源
 
 if __name__ == "__main__":
-    beep()
+    beep()  # 调用蜂鸣函数
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/cloak/cloak.py b/src/sqlmap-master/extra/cloak/cloak.py
index 8f361a0..ee8a396 100644
--- a/src/sqlmap-master/extra/cloak/cloak.py
+++ b/src/sqlmap-master/extra/cloak/cloak.py
@@ -7,82 +7,99 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from __future__ import print_function
+from __future__ import print_function  # 兼容 Python 2 和 3 的 print 函数
 
 import os
 import struct
 import sys
-import zlib
+import zlib  # 用于数据压缩和解压缩
 
 from optparse import OptionError
 from optparse import OptionParser
 
+# 在 Python 3 中定义 xrange 和 ord 的兼容
 if sys.version_info >= (3, 0):
-    xrange = range
-    ord = lambda _: _
+    xrange = range  # 使用 Python 3 的 range
+    ord = lambda _: _  # 在 Python 3 中直接使用字符
 
-KEY = b"E6wRbVhD0IBeCiGJ"
+KEY = b"E6wRbVhD0IBeCiGJ"  # 定义加密/解密的密钥
 
 def xor(message, key):
+    """执行 XOR 操作,返回加密或解密后的字节序列。"""
+    # 对 message 的每个字节进行 XOR 运算,并返回字节串
     return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
 
 def cloak(inputFile=None, data=None):
+    """对输入文件或数据进行加密和压缩。"""
     if data is None:
+        # 如果没有提供数据,则读取文件内容
         with open(inputFile, "rb") as f:
-            data = f.read()
+            data = f.read()  # 以二进制模式读取文件数据
 
+    # 对数据进行压缩后再使用 XOR 加密
     return xor(zlib.compress(data), KEY)
 
 def decloak(inputFile=None, data=None):
+    """对输入文件或数据进行解密和解压缩。"""
     if data is None:
+        # 如果没有提供数据,则读取文件内容
         with open(inputFile, "rb") as f:
             data = f.read()
+
     try:
+        # 首先对数据进行 XOR 解密,然后解压缩
         data = zlib.decompress(xor(data, KEY))
     except Exception as ex:
+        # 如果解压缩过程中发生异常,打印错误信息并退出
         print(ex)
         print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
         sys.exit(1)
     finally:
-        f.close()
+        f.close()  # 确保文件流被关闭
 
-    return data
+    return data  # 返回解密后的数据
 
 def main():
-    usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
-    parser = OptionParser(usage=usage, version='0.2')
+    """主函数,负责解析命令行参数并执行加密或解密操作。"""
+    usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]  # 使用说明
+    parser = OptionParser(usage=usage, version='0.2')  # 创建 OptionParser 对象
 
     try:
-        parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
-        parser.add_option('-i', dest='inputFile', help='Input file')
-        parser.add_option('-o', dest='outputFile', help='Output file')
+        # 添加命令行选项
+        parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')  # 解密选项
+        parser.add_option('-i', dest='inputFile', help='Input file')  # 输入文件选项
+        parser.add_option('-o', dest='outputFile', help='Output file')  # 输出文件选项
 
-        (args, _) = parser.parse_args()
+        (args, _) = parser.parse_args()  # 解析命令行参数
 
         if not args.inputFile:
-            parser.error('Missing the input file, -h for help')
+            parser.error('Missing the input file, -h for help')  # 如果未提供输入文件,则报错
 
     except (OptionError, TypeError) as ex:
-        parser.error(ex)
+        parser.error(ex)  # 捕获解析错误
 
+    # 检查输入文件是否存在
     if not os.path.isfile(args.inputFile):
         print('ERROR: the provided input file \'%s\' is non existent' % args.inputFile)
         sys.exit(1)
 
+    # 根据是否需要解密选择处理函数
     if not args.decrypt:
-        data = cloak(args.inputFile)
+        data = cloak(args.inputFile)  # 加密文件内容
     else:
-        data = decloak(args.inputFile)
+        data = decloak(args.inputFile)  # 解密文件内容
 
+    # 如果未指定输出文件名,则根据是否解密自动生成
     if not args.outputFile:
         if not args.decrypt:
-            args.outputFile = args.inputFile + '_'
+            args.outputFile = args.inputFile + '_'  # 添加后缀表示加密
         else:
-            args.outputFile = args.inputFile[:-1]
+            args.outputFile = args.inputFile[:-1]  # 移除后缀表示解密
 
+    # 写入结果到输出文件
     f = open(args.outputFile, 'wb')
-    f.write(data)
-    f.close()
+    f.write(data)  # 写入数据
+    f.close()  # 关闭文件
 
 if __name__ == '__main__':
-    main()
+    main()  # 程序入口
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/dbgtool/dbgtool.py b/src/sqlmap-master/extra/dbgtool/dbgtool.py
index 5443af7..bc1b1be 100644
--- a/src/sqlmap-master/extra/dbgtool/dbgtool.py
+++ b/src/sqlmap-master/extra/dbgtool/dbgtool.py
@@ -7,7 +7,7 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from __future__ import print_function
+from __future__ import print_function  # 兼容 Python 2 和 3 的 print 函数
 
 import os
 import sys
@@ -16,81 +16,97 @@ from optparse import OptionError
 from optparse import OptionParser
 
 def convert(inputFile):
-    fileStat = os.stat(inputFile)
-    fileSize = fileStat.st_size
+    """将给定的二进制输入文件转换为 ASCII 调试脚本。"""
+    fileStat = os.stat(inputFile)  # 获取文件状态
+    fileSize = fileStat.st_size  # 获取文件大小
 
+    # 检查文件大小是否超过 65280 字节(可调试的最大限制)
     if fileSize > 65280:
         print("ERROR: the provided input file '%s' is too big for debug.exe" % inputFile)
-        sys.exit(1)
+        sys.exit(1)  # 如果文件太大,退出程序
 
-    script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
-    script += "%x\nf 0100 ffff 00\n" % fileSize
-    scrString = ""
-    counter = 256
-    counter2 = 0
+    # 开始构建调试脚本
+    script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))  # 设置脚本名称
+    script += "%x\nf 0100 ffff 00\n" % fileSize  # 写入文件大小信息
+    scrString = ""  # 用于构建写入命令
+    counter = 256  # 地址计数器从 256 开始
+    counter2 = 0  # 0 计数器,用于控制输出的字符数
 
+    # 读取输入文件的二进制内容
     fp = open(inputFile, "rb")
-    fileContent = fp.read()
+    fileContent = fp.read()  # 读取所有内容
 
+    # 遍历文件的每个字节
     for fileChar in fileContent:
+        # 在 Python 3 中字符是字节,直接使用;在 Python 2 中需要使用 ord() 函数
         unsignedFileChar = fileChar if sys.version_info >= (3, 0) else ord(fileChar)
 
+        # 如果字符不是空字节(0),则进行处理
         if unsignedFileChar != 0:
-            counter2 += 1
+            counter2 += 1  # 增加有效字符计数
 
             if not scrString:
+                # 如果 scrString 为空,开始创建新的写入命令
                 scrString = "e %0x %02x" % (counter, unsignedFileChar)
             else:
+                # 否则,将字符附加到 scrString 中
                 scrString += " %02x" % unsignedFileChar
         elif scrString:
+            # 如果遇到空字节,且 scrString 中有内容,需要把当前 scrString 添加到脚本
             script += "%s\n" % scrString
-            scrString = ""
-            counter2 = 0
+            scrString = ""  # 清空 scrString
+            counter2 = 0  # 重置有效字符计数
 
-        counter += 1
+        counter += 1  # 增加地址计数器
 
+        # 每 20 个有效字符输出一次
         if counter2 == 20:
-            script += "%s\n" % scrString
-            scrString = ""
-            counter2 = 0
+            script += "%s\n" % scrString  # 将当前 scrString 加入脚本
+            scrString = ""  # 清空 scrString
+            counter2 = 0  # 重置计数
 
+    # 完成脚本,添加结束指令
     script += "w\nq\n"
 
-    return script
+    return script  # 返回生成的调试脚本
 
 def main(inputFile, outputFile):
+    """主功能,处理文件输入输出。"""
+    # 检查输入文件是否是常规文件
     if not os.path.isfile(inputFile):
         print("ERROR: the provided input file '%s' is not a regular file" % inputFile)
-        sys.exit(1)
+        sys.exit(1)  # 如果不是,退出程序
 
+    # 调用转换函数
     script = convert(inputFile)
 
+    # 如果提供了输出文件,写入脚本
     if outputFile:
-        fpOut = open(outputFile, "w")
-        sys.stdout = fpOut
-        sys.stdout.write(script)
-        sys.stdout.close()
+        with open(outputFile, "w") as fpOut:
+            sys.stdout = fpOut  # 将标准输出重定向到输出文件
+            sys.stdout.write(script)  # 写入脚本内容
+            sys.stdout.close()  # 关闭文件
     else:
-        print(script)
+        print(script)  # 如果没有输出文件,直接打印脚本
 
 if __name__ == "__main__":
-    usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
-    parser = OptionParser(usage=usage, version="0.1")
+    usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]  # 程序用法说明
+    parser = OptionParser(usage=usage, version="0.1")  # 创建解析器
 
     try:
-        parser.add_option("-i", dest="inputFile", help="Input binary file")
-
-        parser.add_option("-o", dest="outputFile", help="Output debug.exe text file")
+        # 添加命令行选项
+        parser.add_option("-i", dest="inputFile", help="Input binary file")  # 输入文件
+        parser.add_option("-o", dest="outputFile", help="Output debug.exe text file")  # 输出文件
 
-        (args, _) = parser.parse_args()
+        (args, _) = parser.parse_args()  # 解析参数
 
         if not args.inputFile:
-            parser.error("Missing the input file, -h for help")
+            parser.error("Missing the input file, -h for help")  # 必须提供输入文件
 
     except (OptionError, TypeError) as ex:
-        parser.error(ex)
+        parser.error(ex)  # 捕获错误并报告
 
-    inputFile = args.inputFile
-    outputFile = args.outputFile
+    inputFile = args.inputFile  # 输入文件名
+    outputFile = args.outputFile  # 输出文件名
 
-    main(inputFile, outputFile)
+    main(inputFile, outputFile)  # 调用主函数
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/icmpsh/icmpsh_m.py b/src/sqlmap-master/extra/icmpsh/icmpsh_m.py
index 17370fd..70de16c 100644
--- a/src/sqlmap-master/extra/icmpsh/icmpsh_m.py
+++ b/src/sqlmap-master/extra/icmpsh/icmpsh_m.py
@@ -5,7 +5,6 @@
 #
 #  Copyright (c) 2010, Bernardo Damele A. G. <bernardo.damele@gmail.com>
 #
-#
 #  This program is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
@@ -28,117 +27,117 @@ def setNonBlocking(fd):
     """
     Make a file descriptor non-blocking
     """
+    import fcntl  # 导入用于文件控制选项的库
 
-    import fcntl
-
-    flags = fcntl.fcntl(fd, fcntl.F_GETFL)
-    flags = flags | os.O_NONBLOCK
-    fcntl.fcntl(fd, fcntl.F_SETFL, flags)
+    flags = fcntl.fcntl(fd, fcntl.F_GETFL)  # 获取当前文件描述符的状态标志
+    flags = flags | os.O_NONBLOCK  # 将非阻塞标志添加到当前标志
+    fcntl.fcntl(fd, fcntl.F_SETFL, flags)  # 设置文件描述符为非阻塞模式
 
 def main(src, dst):
+    """主程序函数,用于设置 ICMP socket 和处理命令。"""
     if sys.platform == "nt":
-        sys.stderr.write('icmpsh master can only run on Posix systems\n')
+        sys.stderr.write('icmpsh master can only run on Posix systems\n')  # 检查是否在 Windows 上运行
         sys.exit(255)
 
     try:
-        from impacket import ImpactDecoder
-        from impacket import ImpactPacket
+        from impacket import ImpactDecoder  # 导入 Impacket 库用于解析数据包
+        from impacket import ImpactPacket  # 导入 Impacket 用于构建数据包
     except ImportError:
-        sys.stderr.write('You need to install Python Impacket library first\n')
+        sys.stderr.write('You need to install Python Impacket library first\n')  # 检查是否安装 Impacket
         sys.exit(255)
 
-    # Make standard input a non-blocking file
-    stdin_fd = sys.stdin.fileno()
+    # 将标准输入设置为非阻塞
+    stdin_fd = sys.stdin.fileno()  # 获取标准输入的文件描述符
     setNonBlocking(stdin_fd)
 
-    # Open one socket for ICMP protocol
-    # A special option is set on the socket so that IP headers are included
-    # with the returned data
+    # 为 ICMP 协议打开一个 socket
     try:
-        sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
+        sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)  # 创建原始 ICMP socket
     except socket.error:
-        sys.stderr.write('You need to run icmpsh master with administrator privileges\n')
+        sys.stderr.write('You need to run icmpsh master with administrator privileges\n')  # 检查运行权限
         sys.exit(1)
 
-    sock.setblocking(0)
-    sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
+    sock.setblocking(0)  # 设置 socket 为非阻塞模式
+    sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)  # 启用 IP 头包含在发送包中
 
-    # Create a new IP packet and set its source and destination addresses
+    # 创建一个新的 IP 包,设置源和目的地址
     ip = ImpactPacket.IP()
-    ip.set_ip_src(src)
-    ip.set_ip_dst(dst)
+    ip.set_ip_src(src)  # 设置源 IP
+    ip.set_ip_dst(dst)  # 设置目标 IP
 
-    # Create a new ICMP packet of type ECHO REPLY
+    # 创建一个新的 ICMP 包,类型为回显应答(ECHO REPLY)
     icmp = ImpactPacket.ICMP()
     icmp.set_icmp_type(icmp.ICMP_ECHOREPLY)
 
-    # Instantiate an IP packets decoder
+    # 实例化 IP 数据包解码器
     decoder = ImpactDecoder.IPDecoder()
 
+    # 在无限循环中发送和接收命令
     while True:
         try:
             cmd = ''
 
-            # Wait for incoming replies
-            if sock in select.select([sock], [], [])[0]:
-                buff = sock.recv(4096)
+            # 等待输入的回复
+            if sock in select.select([sock], [], [])[0]:  # 监控 socket 是否可读
+                buff = sock.recv(4096)  # 接收最大 4096 字节的数据
 
                 if 0 == len(buff):
-                    # Socket remotely closed
+                    # 如果接收到的数据长度为 0,说明对方关闭了 socket
                     sock.close()
                     sys.exit(0)
 
-                # Packet received; decode and display it
-                ippacket = decoder.decode(buff)
-                icmppacket = ippacket.child()
+                # 解析接收到的数据包
+                ippacket = decoder.decode(buff)  # 解码 IP 包
+                icmppacket = ippacket.child()  # 获取 ICMP 包
 
-                # If the packet matches, report it to the user
+                # 检查 ICMP 数据包的源和目的地址以及类型
                 if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type():
-                    # Get identifier and sequence number
+                    # 获取标识符和序列号
                     ident = icmppacket.get_icmp_id()
                     seq_id = icmppacket.get_icmp_seq()
-                    data = icmppacket.get_data_as_string()
+                    data = icmppacket.get_data_as_string()  # 获取数据
 
                     if len(data) > 0:
-                        sys.stdout.write(data)
+                        sys.stdout.write(data)  # 输出接收到的数据
 
-                    # Parse command from standard input
+                    # 从标准输入读取命令
                     try:
-                        cmd = sys.stdin.readline()
+                        cmd = sys.stdin.readline()  # 读取用户输入的命令
                     except:
                         pass
 
-                    if cmd == 'exit\n':
+                    if cmd == 'exit\n':  # 如果输入为 'exit',退出循环
                         return
 
-                    # Set sequence number and identifier
+                    # 设置序列号和标识符,以便回复
                     icmp.set_icmp_id(ident)
                     icmp.set_icmp_seq(seq_id)
 
-                    # Include the command as data inside the ICMP packet
+                    # 将命令作为数据包含在 ICMP 包中
                     icmp.contains(ImpactPacket.Data(cmd))
 
-                    # Calculate its checksum
+                    # 计算 ICMP 包的校验和
                     icmp.set_icmp_cksum(0)
-                    icmp.auto_checksum = 1
+                    icmp.auto_checksum = 1  # 自动计算校验和
 
-                    # Have the IP packet contain the ICMP packet (along with its payload)
+                    # 将 ICMP 包插入到 IP 包中
                     ip.contains(icmp)
 
                     try:
-                        # Send it to the target host
+                        # 发送数据包到目标主机
                         sock.sendto(ip.get_packet(), (dst, 0))
                     except socket.error as ex:
-                        sys.stderr.write("'%s'\n" % ex)
+                        sys.stderr.write("'%s'\n" % ex)  # 输出错误信息
                         sys.stderr.flush()
         except:
             break
 
 if __name__ == '__main__':
+    # 检查参数,确保提供了源 IP 和目标 IP
     if len(sys.argv) < 3:
         msg = 'missing mandatory options. Execute as root:\n'
         msg += './icmpsh-m.py <source IP address> <destination IP address>\n'
         sys.stderr.write(msg)
         sys.exit(1)
 
-    main(sys.argv[1], sys.argv[2])
+    main(sys.argv[1], sys.argv[2])  # 调用主函数,传入源和目标 IP
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp b/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp
index 743f2a2..31ae1f9 100644
--- a/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp
+++ b/src/sqlmap-master/extra/runcmd/src/runcmd/runcmd.cpp
@@ -2,7 +2,7 @@
 	runcmd - a program for running command prompt commands
 	Copyright (C) 2010 Miroslav Stampar
 	email: miroslav.stampar@gmail.com
-	
+
 	This library is free software; you can redistribute it and/or
 	modify it under the terms of the GNU Lesser General Public
 	License as published by the Free Software Foundation; either
@@ -25,22 +25,27 @@
 #include <string>
 
 using namespace std;
+
 int main(int argc, char* argv[])
 {
-  FILE *fp;
-  string cmd;
+  FILE *fp; 
+  string cmd; 
 
-  for( int count = 1; count < argc; count++ )
-	cmd += " " + string(argv[count]);
+  // 从命令行参数获取命令并构建完整的命令字符串
+  for (int count = 1; count < argc; count++)
+    cmd += " " + string(argv[count]); // 将每个参数添加到 cmd 字符串中,并用空格分隔
 
+  // 使用 _popen() 函数以只读的方式打开一个命令进程
   fp = _popen(cmd.c_str(), "r");
 
+  // 检查文件指针是否有效
   if (fp != NULL) {
-    char buffer[BUFSIZ];
+    char buffer[BUFSIZ]; // 声明一个缓冲区用于接收输出
 
+    // 读取命令的输出并将其写到标准输出
     while (fgets(buffer, sizeof buffer, fp) != NULL)
-      fputs(buffer, stdout);
+      fputs(buffer, stdout); // 将缓冲区的内容输出到控制台
   }
 
   return 0;
-}
+}
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/shutils/duplicates.py b/src/sqlmap-master/extra/shutils/duplicates.py
index 8f09a59..df39403 100644
--- a/src/sqlmap-master/extra/shutils/duplicates.py
+++ b/src/sqlmap-master/extra/shutils/duplicates.py
@@ -3,28 +3,32 @@
 # Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 # See the file 'LICENSE' for copying permission
 
-# Removes duplicate entries in wordlist like files
+# Removes duplicate entries in wordlist-like files
 
-from __future__ import print_function
+from __future__ import print_function  # 确保使用 Python 3 的 print() 函数
 
-import sys
+import sys  # 导入系统模块,用于处理命令行参数和文件操作
 
 if __name__ == "__main__":
+    # 检查程序是否接收到至少一个命令行参数
     if len(sys.argv) > 1:
-        items = list()
+        items = list()  # 初始化一个列表用于存储唯一条目
 
+        # 打开指定的文件进行读取
         with open(sys.argv[1], 'r') as f:
-            for item in f:
-                item = item.strip()
+            for item in f:  # 遍历文件中的每一行
+                item = item.strip()  # 去掉行首尾的空白字符
+
                 try:
-                    str.encode(item)
-                    if item in items:
-                        if item:
-                            print(item)
+                    str.encode(item)  # 尝试对字符串编码,确保内容是有效的字符串
+                    if item in items:  # 检查条目是否已经在列表中
+                        if item:  # 确保条目不为空
+                            print(item)  # 打印重复的条目
                     else:
-                        items.append(item)
+                        items.append(item)  # 如果条目不在列表中,则添加到列表
                 except:
-                    pass
+                    pass  # 捕获异常,继续处理下一个条目
 
+        # 以写入模式打开同一个文件,准备写入去重后的唯一条目
         with open(sys.argv[1], 'w+') as f:
-            f.writelines("\n".join(items))
+            f.writelines("\n".join(items))  # 将唯一条目写回文件,以换行符分隔
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/shutils/newlines.py b/src/sqlmap-master/extra/shutils/newlines.py
index fe28a35..a2899b6 100644
--- a/src/sqlmap-master/extra/shutils/newlines.py
+++ b/src/sqlmap-master/extra/shutils/newlines.py
@@ -6,25 +6,30 @@ import os
 import sys
 
 def check(filepath):
-    if filepath.endswith(".py"):
-        content = open(filepath, "rb").read()
-        pattern = "\n\n\n".encode("ascii")
+    # 检查给定路径的文件
+    if filepath.endswith(".py"):  # 检查文件扩展名是否为 .py
+        content = open(filepath, "rb").read()  # 以二进制模式打开文件并读取全部内容
+        pattern = "\n\n\n".encode("ascii")  # 定义一个二进制模式的换行符序列,表示三个换行符
 
+        # 检查内容中是否包含三个连续的换行符
         if pattern in content:
-            index = content.find(pattern)
+            index = content.find(pattern)  # 找到模式在内容中的第一个出现位置
+            # 打印文件路径和模式前后各 30 个字节的内容
             print(filepath, repr(content[index - 30:index + 30]))
 
 if __name__ == "__main__":
     try:
-        BASE_DIRECTORY = sys.argv[1]
-    except IndexError:
+        BASE_DIRECTORY = sys.argv[1]  # 尝试获取命令行中指定的目录路径
+    except IndexError:  # 如果没有指定目录参数
         print("no directory specified, defaulting to current working directory")
-        BASE_DIRECTORY = os.getcwd()
+        BASE_DIRECTORY = os.getcwd()  # 使用当前工作目录作为默认目录
 
     print("looking for *.py scripts in subdirectories of '%s'" % BASE_DIRECTORY)
+    # 遍历指定目录及其子目录中的所有文件
     for root, dirs, files in os.walk(BASE_DIRECTORY):
+        # 如果路径中包含 "extra" 或 "thirdparty",则跳过该目录
         if any(_ in root for _ in ("extra", "thirdparty")):
             continue
-        for name in files:
-            filepath = os.path.join(root, name)
-            check(filepath)
+        for name in files:  # 遍历文件列表
+            filepath = os.path.join(root, name)  # 构建文件的完整路径
+            check(filepath)  # 调用 check 函数检查该文件
\ No newline at end of file
diff --git a/src/sqlmap-master/extra/vulnserver/vulnserver.py b/src/sqlmap-master/extra/vulnserver/vulnserver.py
index cfa1d1b..bb00798 100644
--- a/src/sqlmap-master/extra/vulnserver/vulnserver.py
+++ b/src/sqlmap-master/extra/vulnserver/vulnserver.py
@@ -6,6 +6,9 @@ vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
 Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
+# 该脚本实现了一个简单的 HTTP 服务器,故意留下 SQL 注入漏洞,供测试和学习之用。
+# 它展示了基本的 Web 服务器如何处理请求、解析参数以及如何与 SQLite 数据库交互。
+# 此类工具应仅在安全的实验环境中使用,以避免滥用和安全风险。在实际应用中,开发者应注意保护数据库查询以防止 SQL 注入攻击。
 
 from __future__ import print_function
 
@@ -17,29 +20,26 @@ import sys
 import threading
 import traceback
 
+# 检查 Python 版本
 PY3 = sys.version_info >= (3, 0)
-UNICODE_ENCODING = "utf-8"
-DEBUG = False
+UNICODE_ENCODING = "utf-8"  # 定义 Unicode 编码
+DEBUG = False  # 调试模式标志
 
 if PY3:
-    from http.client import INTERNAL_SERVER_ERROR
-    from http.client import NOT_FOUND
-    from http.client import OK
-    from http.server import BaseHTTPRequestHandler
-    from http.server import HTTPServer
+    # 导入 Python 3 中的 HTTP 相关模块
+    from http.client import INTERNAL_SERVER_ERROR, NOT_FOUND, OK
+    from http.server import BaseHTTPRequestHandler, HTTPServer
     from socketserver import ThreadingMixIn
-    from urllib.parse import parse_qs
-    from urllib.parse import unquote_plus
+    from urllib.parse import parse_qs, unquote_plus
 else:
-    from BaseHTTPServer import BaseHTTPRequestHandler
-    from BaseHTTPServer import HTTPServer
-    from httplib import INTERNAL_SERVER_ERROR
-    from httplib import NOT_FOUND
-    from httplib import OK
+    # 对于 Python 2,导入相应的 HTTP 相关模块
+    from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+    from httplib import INTERNAL_SERVER_ERROR, NOT_FOUND, OK
     from SocketServer import ThreadingMixIn
     from urlparse import parse_qs
     from urllib import unquote_plus
 
+# SQLite 模式定义,创建用户表并插入示例数据
 SCHEMA = """
     CREATE TABLE users (
         id INTEGER,
@@ -54,9 +54,11 @@ SCHEMA = """
     INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull');
 """
 
+# 定义监听地址和端口
 LISTEN_ADDRESS = "localhost"
 LISTEN_PORT = 8440
 
+# 全局变量
 _conn = None
 _cursor = None
 _lock = None
@@ -68,13 +70,15 @@ def init(quiet=False):
     global _cursor
     global _lock
 
+    # 在内存中创建 SQLite 数据库连接
     _conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
-    _cursor = _conn.cursor()
-    _lock = threading.Lock()
+    _cursor = _conn.cursor()  # 创建游标,用于执行 SQL 命令
+    _lock = threading.Lock()  # 创建线程锁,以处理多线程环境下的数据库访问
 
-    _cursor.executescript(SCHEMA)
+    _cursor.executescript(SCHEMA)  # 执行脚本以创建表并插入数据
 
     if quiet:
+        # 如果 quiet 为 True,则禁止输出
         global print
 
         def _(*args, **kwargs):
@@ -83,6 +87,7 @@ def init(quiet=False):
         print = _
 
 class ThreadingServer(ThreadingMixIn, HTTPServer):
+    # 允许多线程处理 HTTP 请求
     def finish_request(self, *args, **kwargs):
         try:
             HTTPServer.finish_request(self, *args, **kwargs)
@@ -91,13 +96,16 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
                 traceback.print_exc()
 
 class ReqHandler(BaseHTTPRequestHandler):
+    # 请求处理类
     def do_REQUEST(self):
+        # 处理请求,分割路径和查询字符串
         path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
         params = {}
 
         if query:
-            params.update(parse_qs(query))
+            params.update(parse_qs(query))  # 解析查询字符串为字典
 
+            # 检查是否出现恶意脚本
             if "<script>" in unquote_plus(query):
                 self.send_response(INTERNAL_SERVER_ERROR)
                 self.send_header("X-Powered-By", "Express")
@@ -106,18 +114,25 @@ class ReqHandler(BaseHTTPRequestHandler):
                 self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode(UNICODE_ENCODING))
                 return
 
+        # 处理请求数据(如果有)
         if hasattr(self, "data"):
             if self.data.startswith('{') and self.data.endswith('}'):
-                params.update(json.loads(self.data))
+                params.update(json.loads(self.data))  # JSON 数据
             elif self.data.startswith('<') and self.data.endswith('>'):
-                params.update(dict((_[0], _[1].replace("&apos;", "'").replace("&quot;", '"').replace("&lt;", '<').replace("&gt;", '>').replace("&amp;", '&')) for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data)))
+                # 解析 HTML 表单数据
+                params.update(dict((_[0], _[1].replace("&apos;", "'").replace("&quot;", '"')
+                                    .replace("&lt;", '<').replace("&gt;", '>').replace("&amp;", '&'))
+                                   for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data)))
             else:
-                self.data = self.data.replace(';', '&')     # Note: seems that Python3 started ignoring parameter splitting with ';'
+                # 处理 URL 编码数据
+                self.data = self.data.replace(';', '&')  # 兼容性处理
                 params.update(parse_qs(self.data))
 
+        # 处理请求头参数
         for name in self.headers:
             params[name.lower()] = self.headers[name]
 
+        # 处理 Cookie 参数
         if "cookie" in params:
             for part in params["cookie"].split(';'):
                 part = part.strip()
@@ -125,14 +140,17 @@ class ReqHandler(BaseHTTPRequestHandler):
                     name, value = part.split('=', 1)
                     params[name.strip()] = unquote_plus(value.strip())
 
+        # 将多值参数转换为单值
         for key in params:
             if params[key] and isinstance(params[key], (tuple, list)):
                 params[key] = params[key][-1]
 
-        self.url, self.params = path, params
+        self.url, self.params = path, params  # 存储 URL 和参数
 
         if self.url == '/':
+            # 主页处理
             if not any(_ in self.params for _ in ("id", "query")):
+                # 如果没有 ID 或查询参数,则显示主页面
                 self.send_response(OK)
                 self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
                 self.send_header("Connection", "close")
@@ -142,27 +160,33 @@ class ReqHandler(BaseHTTPRequestHandler):
                 code, output = OK, ""
 
                 try:
+                    # 处理回显参数
                     if self.params.get("echo", ""):
                         output += "%s<br>" % self.params["echo"]
 
                     if self.params.get("reflect", ""):
                         output += "%s<br>" % self.params.get("id")
 
-                    with _lock:
+                    with _lock:  # 使用锁来确保线程安全
                         if "query" in self.params:
+                            # 执行任意 SQL 查询
                             _cursor.execute(self.params["query"])
                         elif "id" in self.params:
+                            # 通过 ID 查询用户
                             if "base64" in self.params:
-                                _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode())
+                                _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" %
+                                                base64.b64decode("%s===" % self.params["id"],
+                                                altchars=self.params.get("altchars")).decode())
                             else:
                                 _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
-                        results = _cursor.fetchall()
+                        results = _cursor.fetchall()  # 获取查询结果
 
                     output += "<b>SQL results:</b><br>\n"
 
+                    # 根据查询结果决定响应的状态码和内容
                     if self.params.get("code", ""):
                         if not results:
-                            code = INTERNAL_SERVER_ERROR
+                            code = INTERNAL_SERVER_ERROR  # 出错
                     else:
                         if results:
                             output += "<table border=\"1\">\n"
@@ -175,15 +199,16 @@ class ReqHandler(BaseHTTPRequestHandler):
 
                             output += "</table>\n"
                         else:
-                            output += "no results found"
+                            output += "no results found"  # 查询无结果
 
                     output += "</body></html>"
                 except Exception as ex:
                     code = INTERNAL_SERVER_ERROR
+                    # 捕获异常并返回错误信息
                     output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex)
 
+                # 发送响应
                 self.send_response(code)
-
                 self.send_header("Content-type", "text/html")
                 self.send_header("Connection", "close")
 
@@ -194,26 +219,30 @@ class ReqHandler(BaseHTTPRequestHandler):
                     self.end_headers()
                     self.wfile.write(output if isinstance(output, bytes) else output.encode(UNICODE_ENCODING))
         else:
+            # 对于未定义的路径返回 404
             self.send_response(NOT_FOUND)
             self.send_header("Connection", "close")
             self.end_headers()
 
     def do_GET(self):
-        self.do_REQUEST()
+        self.do_REQUEST()  # 处理 GET 请求
 
     def do_PUT(self):
-        self.do_POST()
+        self.do_POST()  # 处理 PUT 请求
 
     def do_HEAD(self):
-        self.do_REQUEST()
+        self.do_REQUEST()  # 处理 HEAD 请求
 
     def do_POST(self):
+        # 处理 POST 请求
         length = int(self.headers.get("Content-length", 0))
         if length:
+            # 读取请求体数据
             data = self.rfile.read(length)
             data = unquote_plus(data.decode(UNICODE_ENCODING, "ignore"))
             self.data = data
         elif self.headers.get("Transfer-encoding") == "chunked":
+            # 处理 chunked 请求
             data, line = b"", b""
             count = 0
 
@@ -232,10 +261,10 @@ class ReqHandler(BaseHTTPRequestHandler):
 
             self.data = data.decode(UNICODE_ENCODING, "ignore")
 
-        self.do_REQUEST()
+        self.do_REQUEST()  # 处理 POST 逻辑
 
     def log_message(self, format, *args):
-        return
+        return  # 不记录日志
 
 def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
     global _alive
@@ -244,16 +273,17 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
         _alive = True
         _server = ThreadingServer((address, port), ReqHandler)
         print("[i] running HTTP server at 'http://%s:%d'" % (address, port))
-        _server.serve_forever()
+        _server.serve_forever()  # 开始监听并处理请求
     except KeyboardInterrupt:
-        _server.socket.close()
+        _server.socket.close()  # 关闭服务器
         raise
     finally:
         _alive = False
 
 if __name__ == "__main__":
     try:
-        init()
-        run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
+        init()  # 初始化数据库和服务器
+        run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS,
+            int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
     except KeyboardInterrupt:
-        print("\r[x] Ctrl-C received")
+        print("\r[x] Ctrl-C received")  # 捕获 Ctrl-C 终止信号
\ No newline at end of file
diff --git a/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png b/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/blind_classes_blind.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png b/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png
new file mode 100644
index 0000000..11484b3
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/blind_packages_blind.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png b/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/controller_classes_controller.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png b/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png
new file mode 100644
index 0000000..e4ca890
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/controller_packages_controller.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/core_classes_core.png b/src/sqlmap-master/lib/class_diagram/core_classes_core.png
new file mode 100644
index 0000000..4e0f3a8
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/core_classes_core.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/core_packages_core.png b/src/sqlmap-master/lib/class_diagram/core_packages_core.png
new file mode 100644
index 0000000..03f35fa
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/core_packages_core.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png b/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/dns_classes_dns.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png b/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png
new file mode 100644
index 0000000..3c73804
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/dns_packages_dns.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/error_classes_error.png b/src/sqlmap-master/lib/class_diagram/error_classes_error.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/error_classes_error.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/error_packages_error.png b/src/sqlmap-master/lib/class_diagram/error_packages_error.png
new file mode 100644
index 0000000..0c1eedf
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/error_packages_error.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png b/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png
new file mode 100644
index 0000000..f0acca2
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/parse_classes_parse.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png b/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png
new file mode 100644
index 0000000..18a478b
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/parse_packages_parse.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/request_classes_request.png b/src/sqlmap-master/lib/class_diagram/request_classes_request.png
new file mode 100644
index 0000000..aa6d21f
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/request_classes_request.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/request_packages_request.png b/src/sqlmap-master/lib/class_diagram/request_packages_request.png
new file mode 100644
index 0000000..319c7bc
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/request_packages_request.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png b/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png
new file mode 100644
index 0000000..390cad8
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/takeover_classes_takeover.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png b/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png
new file mode 100644
index 0000000..260706c
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/takeover_packages_takeover.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png b/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/techniques_classes_techniques.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png b/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png
new file mode 100644
index 0000000..3fb3d13
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/techniques_packages_techniques.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/union_classes_union.png b/src/sqlmap-master/lib/class_diagram/union_classes_union.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/union_classes_union.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/union_packages_union.png b/src/sqlmap-master/lib/class_diagram/union_packages_union.png
new file mode 100644
index 0000000..6a34f3a
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/union_packages_union.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png b/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png
new file mode 100644
index 0000000..66aec56
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/utils_classes_utils.png differ
diff --git a/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png b/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png
new file mode 100644
index 0000000..192aa84
Binary files /dev/null and b/src/sqlmap-master/lib/class_diagram/utils_packages_utils.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png b/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png
new file mode 100644
index 0000000..c8716f0
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/access_classes_access.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png b/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png
new file mode 100644
index 0000000..421495a
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/access_packages_access.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png
new file mode 100644
index 0000000..ceffc56
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_classes_altibase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png
new file mode 100644
index 0000000..b11b497
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/altibase_packages_altibase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png b/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png
new file mode 100644
index 0000000..b81383c
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cache_classes_cache.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png b/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png
new file mode 100644
index 0000000..285d370
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cache_packages_cache.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png
new file mode 100644
index 0000000..68d9343
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_classes_clickhouse.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png
new file mode 100644
index 0000000..b46b913
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/clickhouse_packages_clickhouse.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png
new file mode 100644
index 0000000..f54cc4d
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_classes_cratedb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png
new file mode 100644
index 0000000..1cd17d8
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cratedb_packages_cratedb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png
new file mode 100644
index 0000000..034e8eb
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_classes_cubrid.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png
new file mode 100644
index 0000000..e0e064c
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/cubrid_packages_cubrid.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png b/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png
new file mode 100644
index 0000000..d11ff5a
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/db2_classes_db2.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png b/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png
new file mode 100644
index 0000000..336f656
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/db2_packages_db2.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png b/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png
new file mode 100644
index 0000000..a3b7350
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/derby_classes_derby.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png b/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png
new file mode 100644
index 0000000..e5e57a2
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/derby_packages_derby.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png
new file mode 100644
index 0000000..feda6ac
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_classes_extremedb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png
new file mode 100644
index 0000000..29a17f1
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/extremedb_packages_extremedb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png
new file mode 100644
index 0000000..dfa47db
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_classes_firebird.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png
new file mode 100644
index 0000000..af96735
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/firebird_packages_firebird.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png
new file mode 100644
index 0000000..079b591
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_classes_frontbase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png
new file mode 100644
index 0000000..9c81518
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/frontbase_packages_frontbase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png b/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png
new file mode 100644
index 0000000..496383d
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/h2_classes_h2.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png b/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png
new file mode 100644
index 0000000..7b977e8
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/h2_packages_h2.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png
new file mode 100644
index 0000000..2a3ffa0
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_classes_hsqldb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png
new file mode 100644
index 0000000..89c66ce
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/hsqldb_packages_hsqldb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png b/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png
new file mode 100644
index 0000000..cbc5977
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/informix_classes_informix.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png b/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png
new file mode 100644
index 0000000..0f46bc6
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/informix_packages_informix.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png
new file mode 100644
index 0000000..6d80090
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_classes_maxdb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png
new file mode 100644
index 0000000..89cc076
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/maxdb_packages_maxdb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png
new file mode 100644
index 0000000..e7c65ed
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_classes_mckoi.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png
new file mode 100644
index 0000000..b8c92f8
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mckoi_packages_mckoi.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png
new file mode 100644
index 0000000..4d25a81
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_classes_mimersql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png
new file mode 100644
index 0000000..2f563ef
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mimersql_packages_mimersql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png
new file mode 100644
index 0000000..a5a7d8a
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_classes_monetdb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png
new file mode 100644
index 0000000..2ed9a4b
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/monetdb_packages_monetdb.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png
new file mode 100644
index 0000000..ddc61ac
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_classes_mssqlserver.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png
new file mode 100644
index 0000000..ef94b07
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mssqlserver_packages_mssqlserver.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png
new file mode 100644
index 0000000..9eaea2f
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_classes_mysql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png
new file mode 100644
index 0000000..018e829
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/mysql_packages_mysql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png
new file mode 100644
index 0000000..92bccd2
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_classes_oracle.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png
new file mode 100644
index 0000000..28489bd
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/oracle_packages_oracle.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png
new file mode 100644
index 0000000..a5ad53d
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_classes_postgresql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png
new file mode 100644
index 0000000..a92b34a
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/postgresql_packages_postgresql.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png b/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png
new file mode 100644
index 0000000..305d35e
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/presto_classes_presto.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png b/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png
new file mode 100644
index 0000000..f41e9b6
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/presto_packages_presto.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png b/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png
new file mode 100644
index 0000000..c69870a
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/raima_classes_raima.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png b/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png
new file mode 100644
index 0000000..0034ecd
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/raima_packages_raima.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png
new file mode 100644
index 0000000..1823aa4
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_classes_sqlite.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png
new file mode 100644
index 0000000..54bb312
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sqlite_packages_sqlite.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png
new file mode 100644
index 0000000..97471ba
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_classes_sybase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png
new file mode 100644
index 0000000..043c8f8
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/sybase_packages_sybase.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png
new file mode 100644
index 0000000..40e2f28
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_classes_vertica.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png
new file mode 100644
index 0000000..fea71c3
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/vertica_packages_vertica.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png
new file mode 100644
index 0000000..0118466
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_classes_virtuoso.png differ
diff --git a/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png
new file mode 100644
index 0000000..39686ca
Binary files /dev/null and b/src/sqlmap-master/plugins/dbms/class_diagram/virtuoso_packages_virtuoso.png differ
diff --git a/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py b/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py
index b676f69..8fa5a43 100644
--- a/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py
+++ b/src/sqlmap-master/plugins/dbms/maxdb/enumeration.py
@@ -32,40 +32,47 @@ from thirdparty.six.moves import zip as _zip
 class Enumeration(GenericEnumeration):
     def __init__(self):
         GenericEnumeration.__init__(self)
-
+        # 将缓存的数据处理字符中的下划线替换为空格
         kb.data.processChar = lambda x: x.replace('_', ' ') if x else x
 
     def getPasswordHashes(self):
+        # 输出警告信息,因SAP MaxDB不支持用户密码哈希的枚举
         warnMsg = "on SAP MaxDB it is not possible to enumerate the user password hashes"
         logger.warning(warnMsg)
 
         return {}
 
     def getDbs(self):
+        # 若缓存的数据库信息不为空则返回缓存内容
         if len(kb.data.cachedDbs) > 0:
             return kb.data.cachedDbs
 
         infoMsg = "fetching database names"
         logger.info(infoMsg)
 
+        # 查询数据库名称的SQL语句
         rootQuery = queries[DBMS.MAXDB].dbs
         query = rootQuery.inband.query
         retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.schemaname' % kb.aliasName], blind=True)
 
+        # 如果查询结果有效,缓存数据库名称
         if retVal:
             kb.data.cachedDbs = next(six.itervalues(retVal[0]))
 
+        # 对数据库名称进行排序
         if kb.data.cachedDbs:
             kb.data.cachedDbs.sort()
 
         return kb.data.cachedDbs
 
     def getTables(self, bruteForce=None):
+        # 如果缓存的表信息不为空,则返回缓存内容
         if len(kb.data.cachedTables) > 0:
             return kb.data.cachedTables
 
         self.forceDbmsEnum()
 
+        # 根据当前选中的数据库获取数据库名称
         if conf.db == CURRENT_DB:
             conf.db = self.getCurrentDb()
 
@@ -74,6 +81,7 @@ class Enumeration(GenericEnumeration):
         else:
             dbs = self.getDbs()
 
+        # 对数据库名称进行安全处理
         for db in (_ for _ in dbs if _):
             dbs[dbs.index(db)] = safeSQLIdentificatorNaming(db)
 
@@ -83,6 +91,7 @@ class Enumeration(GenericEnumeration):
 
         rootQuery = queries[DBMS.MAXDB].tables
 
+        # 遍历每个数据库,查询表名称
         for db in dbs:
             query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
             blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
@@ -95,6 +104,7 @@ class Enumeration(GenericEnumeration):
                     else:
                         kb.data.cachedTables[db].append(table)
 
+        # 对每个数据库的表进行排序
         for db, tables in kb.data.cachedTables.items():
             kb.data.cachedTables[db] = sorted(tables) if tables else tables
 
@@ -103,6 +113,7 @@ class Enumeration(GenericEnumeration):
     def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None, dumpMode=False):
         self.forceDbmsEnum()
 
+        # 获取当前选中的数据库
         if conf.db is None or conf.db == CURRENT_DB:
             if conf.db is None:
                 warnMsg = "missing database parameter. sqlmap is going "
@@ -118,19 +129,24 @@ class Enumeration(GenericEnumeration):
                 errMsg += "the tables' columns"
                 raise SqlmapMissingMandatoryOptionException(errMsg)
 
+        # 对数据库名称进行安全处理
         conf.db = safeSQLIdentificatorNaming(conf.db)
 
+        # 获取需要查询的列名
         if conf.col:
             colList = conf.col.split(',')
         else:
             colList = []
 
+        # 处理排除的列名
         if conf.exclude:
             colList = [_ for _ in colList if re.search(conf.exclude, _, re.I) is None]
 
+        # 对列名进行安全处理
         for col in colList:
             colList[colList.index(col)] = safeSQLIdentificatorNaming(col)
 
+        # 获取需要查询的表名
         if conf.tbl:
             tblList = conf.tbl.split(',')
         else:
@@ -146,12 +162,14 @@ class Enumeration(GenericEnumeration):
                 errMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
                 raise SqlmapNoneDataException(errMsg)
 
+        # 对表名进行安全处理
         for tbl in tblList:
             tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True)
 
         if bruteForce:
             resumeAvailable = False
 
+            # 检查列名是否已存在于缓存中
             for tbl in tblList:
                 for db, table, colName, colType in kb.brute.columns:
                     if db == conf.db and table == tbl:
@@ -188,6 +206,7 @@ class Enumeration(GenericEnumeration):
 
         rootQuery = queries[DBMS.MAXDB].columns
 
+        # 遍历每个表,查询列名称及数据类型
         for tbl in tblList:
             if conf.db is not None and len(kb.data.cachedColumns) > 0 and conf.db in kb.data.cachedColumns and tbl in kb.data.cachedColumns[conf.db]:
                 infoMsg = "fetched tables' columns on "
@@ -196,6 +215,7 @@ class Enumeration(GenericEnumeration):
 
                 return {conf.db: kb.data.cachedColumns[conf.db]}
 
+            # 在剩余模式且限制列名时,继续缓存
             if dumpMode and colList:
                 table = {}
                 table[safeSQLIdentificatorNaming(tbl, True)] = dict((_, None) for _ in colList)
@@ -209,6 +229,7 @@ class Enumeration(GenericEnumeration):
 
             blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
 
+            # 查询表的列名称和数据类型的SQL语句
             query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
             retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=blind)
 
@@ -216,6 +237,7 @@ class Enumeration(GenericEnumeration):
                 table = {}
                 columns = {}
 
+                # 将查询结果中的列名和数据类型进行处理
                 for columnname, datatype, length in _zip(retVal[0]["%s.columnname" % kb.aliasName], retVal[0]["%s.datatype" % kb.aliasName], retVal[0]["%s.len" % kb.aliasName]):
                     columns[safeSQLIdentificatorNaming(columnname)] = "%s(%s)" % (datatype, length)
 
@@ -225,21 +247,25 @@ class Enumeration(GenericEnumeration):
         return kb.data.cachedColumns
 
     def getPrivileges(self, *args, **kwargs):
+        # 输出警告信息,因SAP MaxDB不支持用户权限的枚举
         warnMsg = "on SAP MaxDB it is not possible to enumerate the user privileges"
         logger.warning(warnMsg)
 
         return {}
 
     def search(self):
+        # 输出警告,表示SAP MaxDB不支持搜索功能
         warnMsg = "on SAP MaxDB search option is not available"
         logger.warning(warnMsg)
 
     def getHostname(self):
+        # 输出警告信息,因SAP MaxDB不支持主机名的枚举
         warnMsg = "on SAP MaxDB it is not possible to enumerate the hostname"
         logger.warning(warnMsg)
 
     def getStatements(self):
+        # 输出警告信息,因SAP MaxDB不支持SQL语句的枚举
         warnMsg = "on SAP MaxDB it is not possible to enumerate the SQL statements"
         logger.warning(warnMsg)
 
-        return []
+        return []
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py b/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py
index a60bc65..1c686ab 100644
--- a/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py
+++ b/src/sqlmap-master/plugins/dbms/maxdb/fingerprint.py
@@ -21,12 +21,19 @@ from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
 class Fingerprint(GenericFingerprint):
     def __init__(self):
+        """
+        初始化Fingerprint类,指定为SAP MaxDB。
+        """
         GenericFingerprint.__init__(self, DBMS.MAXDB)
 
     def _versionCheck(self):
+        """
+        执行SAP MaxDB的SYSINFO版本检查。
+        """
         infoMsg = "executing %s SYSINFO version check" % DBMS.MAXDB
         logger.info(infoMsg)
 
+        # 构建查询语句
         query = agent.prefixQuery("/* NoValue */")
         query = agent.suffixQuery(query)
         payload = agent.payload(newValue=query)
@@ -40,12 +47,14 @@ class Fingerprint(GenericFingerprint):
 
         minor, major = None, None
 
+        # 检查主要版本号
         for version in (6, 7):
             result = inject.checkBooleanExpression("%d=(SELECT MAJORVERSION FROM SYSINFO.VERSION)" % version)
 
             if result:
                 major = version
 
+        # 检查次要版本号
         for version in xrange(0, 10):
             result = inject.checkBooleanExpression("%d=(SELECT MINORVERSION FROM SYSINFO.VERSION)" % version)
 
@@ -58,12 +67,17 @@ class Fingerprint(GenericFingerprint):
             return None
 
     def getFingerprint(self):
+        """
+        获取指纹信息。
+        """
         value = ""
+        # 获取Web服务器的操作系统指纹
         wsOsFp = Format.getOs("web server", kb.headersFp)
 
         if wsOsFp:
             value += "%s\n" % wsOsFp
 
+        # 获取后端数据库的操作系统指纹
         if kb.data.banner:
             dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
 
@@ -77,6 +91,7 @@ class Fingerprint(GenericFingerprint):
             value += DBMS.MAXDB
             return value
 
+        # 获取活性指纹
         actVer = Format.getDbms() + " (%s)" % self._versionCheck()
         blank = " " * 15
         value += "active fingerprint: %s" % actVer
@@ -84,6 +99,7 @@ class Fingerprint(GenericFingerprint):
         if kb.bannerFp:
             value += "\n%sbanner parsing fingerprint: -" % blank
 
+        # 获取HTML错误消息指纹
         htmlErrorFp = Format.getErrorParsedDBMSes()
 
         if htmlErrorFp:
@@ -92,9 +108,13 @@ class Fingerprint(GenericFingerprint):
         return value
 
     def checkDbms(self):
+        """
+        检测后端数据库是否为SAP MaxDB。
+        """
         if not conf.extensiveFp and Backend.isDbmsWithin(MAXDB_ALIASES):
             setDbms(DBMS.MAXDB)
 
+            # 获取Banner信息
             self.getBanner()
 
             return True
@@ -102,12 +122,14 @@ class Fingerprint(GenericFingerprint):
         infoMsg = "testing %s" % DBMS.MAXDB
         logger.info(infoMsg)
 
+        # 检查ALPHA(NULL)是否为NULL
         result = inject.checkBooleanExpression("ALPHA(NULL) IS NULL")
 
         if result:
             infoMsg = "confirming %s" % DBMS.MAXDB
             logger.info(infoMsg)
 
+            # 检查MAPCHAR(NULL,1,DEFAULTMAP)是否为NULL
             result = inject.checkBooleanExpression("MAPCHAR(NULL,1,DEFAULTMAP) IS NULL")
 
             if not result:
@@ -128,10 +150,13 @@ class Fingerprint(GenericFingerprint):
             return False
 
     def forceDbmsEnum(self):
+        """
+        强制进行数据库枚举。
+        """
         if conf.db:
             conf.db = conf.db.upper()
         else:
             conf.db = "USER"
 
         if conf.tbl:
-            conf.tbl = conf.tbl.upper()
+            conf.tbl = conf.tbl.upper()
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/dbms/mysql/connector.py b/src/sqlmap-master/plugins/dbms/mysql/connector.py
index e965bfe..266cb93 100644
--- a/src/sqlmap-master/plugins/dbms/mysql/connector.py
+++ b/src/sqlmap-master/plugins/dbms/mysql/connector.py
@@ -13,11 +13,12 @@ except:
 import logging
 import struct
 
-from lib.core.common import getSafeExString
-from lib.core.data import conf
-from lib.core.data import logger
-from lib.core.exception import SqlmapConnectionException
-from plugins.generic.connector import Connector as GenericConnector
+from lib.core.common import getSafeExString # 用于安全获取异常字符串的函数
+from lib.core.data import conf  # sqlmap的配置管理
+from lib.core.data import logger # sqlmap的日志记录模块
+from lib.core.exception import SqlmapConnectionException # 自定义的连接异常
+from plugins.generic.connector import Connector as GenericConnector  # 基础连接类
+
 
 class Connector(GenericConnector):
     """
@@ -30,17 +31,28 @@ class Connector(GenericConnector):
     """
 
     def connect(self):
+        """
+        初始化到MySQL数据库的连接。
+        使用提供的凭据和配置设置建立连接。
+        """
         self.initConnection()
 
         try:
-            self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True)
+            self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True) # 确保使用Unicode进行字符编码
         except (pymysql.OperationalError, pymysql.InternalError, pymysql.ProgrammingError, struct.error) as ex:
+            # 如果在连接期间发生错误,抛出连接异常
             raise SqlmapConnectionException(getSafeExString(ex))
 
-        self.initCursor()
-        self.printConnected()
+        self.initCursor()  # 初始化用于执行查询的游标
+        self.printConnected() # 记录连接成功的信息
 
     def fetchall(self):
+        """
+        从游标结果集中获取所有行。
+        
+        返回:
+            从数据库获取的行列表,或者在发生错误时返回None。
+        """
         try:
             return self.cursor.fetchall()
         except pymysql.ProgrammingError as ex:
@@ -48,6 +60,17 @@ class Connector(GenericConnector):
             return None
 
     def execute(self, query):
+
+        """
+        在数据库上执行SQL查询。
+
+        参数:
+            query (str): 要执行的SQL查询。
+
+        返回:
+            bool: 如果查询成功执行,返回True;否则返回False。
+        """
+
         retVal = False
 
         try:
@@ -63,6 +86,15 @@ class Connector(GenericConnector):
         return retVal
 
     def select(self, query):
+        """
+        执行SELECT SQL查询并返回结果。
+
+        参数:
+            query (str): 要执行的SELECT SQL查询。
+
+        返回:
+            从数据库获取的行列表,或者如果执行失败则返回None。
+        """
         retVal = None
 
         if self.execute(query):
diff --git a/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py b/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py
index 5f32b4f..4f4b4ec 100644
--- a/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py
+++ b/src/sqlmap-master/plugins/dbms/sqlite/fingerprint.py
@@ -17,17 +17,23 @@ from lib.core.settings import SQLITE_ALIASES
 from lib.request import inject
 from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
 
+# 该插件用于检测sqlite数据库,通过执行一些常用函数来判断数据库类型,并获取数据库版本信息,最后返回检测结果。 
+# 通过执行SQLITE_VERSION()函数来判断数据库类型,获取数据库版本信息,检测数据库是否存在。
+
 class Fingerprint(GenericFingerprint):
     def __init__(self):
+        # 初始化父类Fingerprint,对象的数据库管理系统类型设置为SQLite
         GenericFingerprint.__init__(self, DBMS.SQLITE)
 
     def getFingerprint(self):
         value = ""
+        # 获取Web服务器的操作系统指纹
         wsOsFp = Format.getOs("web server", kb.headersFp)
 
         if wsOsFp:
             value += "%s\n" % wsOsFp
 
+        # 获取数据库服务器的操作系统指纹
         if kb.data.banner:
             dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
 
@@ -36,14 +42,17 @@ class Fingerprint(GenericFingerprint):
 
         value += "back-end DBMS: "
 
+        # 如果不是详尽指纹模式,直接返回DBMS类型
         if not conf.extensiveFp:
             value += DBMS.SQLITE
             return value
 
+        # 获取当前活动的数据库管理系统信息
         actVer = Format.getDbms()
         blank = " " * 15
         value += "active fingerprint: %s" % actVer
 
+        # 如果有数据库版本信息的指纹,则进行处理
         if kb.bannerFp:
             banVer = kb.bannerFp.get("dbmsVersion")
 
@@ -51,6 +60,7 @@ class Fingerprint(GenericFingerprint):
                 banVer = Format.getDbms([banVer])
                 value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
 
+        # 获取HTML错误消息中的指纹
         htmlErrorFp = Format.getErrorParsedDBMSes()
 
         if htmlErrorFp:
@@ -66,6 +76,7 @@ class Fingerprint(GenericFingerprint):
         * http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions
         """
 
+        # 如果不是详尽指纹模式并且数据库管理系统在已知的SQLite别名之中
         if not conf.extensiveFp and Backend.isDbmsWithin(SQLITE_ALIASES):
             setDbms(DBMS.SQLITE)
 
@@ -76,12 +87,14 @@ class Fingerprint(GenericFingerprint):
         infoMsg = "testing %s" % DBMS.SQLITE
         logger.info(infoMsg)
 
+        # 检查布尔表达式,验证是否为SQLite
         result = inject.checkBooleanExpression("LAST_INSERT_ROWID()=LAST_INSERT_ROWID()")
 
         if result:
             infoMsg = "confirming %s" % DBMS.SQLITE
             logger.info(infoMsg)
 
+            # 进一步确认数据库版本
             result = inject.checkBooleanExpression("SQLITE_VERSION()=SQLITE_VERSION()")
 
             if not result:
@@ -93,6 +106,7 @@ class Fingerprint(GenericFingerprint):
                 infoMsg = "actively fingerprinting %s" % DBMS.SQLITE
                 logger.info(infoMsg)
 
+                # 依据RANDOMBLOB函数确定SQLite版本
                 result = inject.checkBooleanExpression("RANDOMBLOB(-1)>0")
                 version = '3' if result else '2'
                 Backend.setVersion(version)
@@ -109,4 +123,5 @@ class Fingerprint(GenericFingerprint):
             return False
 
     def forceDbmsEnum(self):
+        # 强制数据库管理系统枚举,设置数据库名称
         conf.db = "%s%s" % (DBMS.SQLITE, METADB_SUFFIX)
diff --git a/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png b/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/class_diagram_classes_class_diagram.png differ
diff --git a/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png b/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png
new file mode 100644
index 0000000..7994a60
Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/generic_classes_generic.png differ
diff --git a/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png b/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png
new file mode 100644
index 0000000..a37df7d
Binary files /dev/null and b/src/sqlmap-master/plugins/generic/class_diagram/generic_packages_generic.png differ
diff --git a/src/sqlmap-master/sqlmap.py b/src/sqlmap-master/sqlmap.py
index 70fb972..cd8385d 100644
--- a/src/sqlmap-master/sqlmap.py
+++ b/src/sqlmap-master/sqlmap.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 """
-Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) 
 See the file 'LICENSE' for copying permission
 """
 
@@ -10,13 +10,16 @@ from __future__ import print_function
 try:
     import sys
 
+    # 防止Python自动生成.pyc文件
     sys.dont_write_bytecode = True
 
     try:
+        # 检查sqlmap的安装是否正确
         __import__("lib.utils.versioncheck")  # this has to be the first non-standard import
     except ImportError:
         sys.exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details")
 
+    # 导入标准库模块
     import bdb
     import glob
     import inspect
@@ -32,6 +35,7 @@ try:
     import traceback
     import warnings
 
+    # 忽略DeprecationWarning,除非命令行参数中包含"--deprecations"
     if "--deprecations" not in sys.argv:
         warnings.filterwarnings(action="ignore", category=DeprecationWarning)
     else:
@@ -41,14 +45,17 @@ try:
         if sys.version_info >= (3, 0):
             warnings.simplefilter("ignore", category=ResourceWarning)
 
+    # 忽略特定警告
     warnings.filterwarnings(action="ignore", message="Python 2 is no longer supported")
     warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
     warnings.filterwarnings(action="ignore", message=".*using a very old release", category=UserWarning)
     warnings.filterwarnings(action="ignore", message=".*default buffer size will be used", category=RuntimeWarning)
     warnings.filterwarnings(action="ignore", category=UserWarning, module="psycopg2")
 
+    # 导入sqlmap的核心日志模块
     from lib.core.data import logger
 
+    # 导入sqlmap的核心功能模块
     from lib.core.common import banner
     from lib.core.common import checkPipedInput
     from lib.core.common import checkSums
@@ -90,6 +97,8 @@ try:
     from lib.core.settings import VERSION
     from lib.parse.cmdline import cmdLineParser
     from lib.utils.crawler import crawl
+except Exception as ex:
+    print("An error occurred: " + str(ex))
 except KeyboardInterrupt:
     errMsg = "user aborted"
 
@@ -102,26 +111,38 @@ except KeyboardInterrupt:
 
 def modulePath():
     """
-    This will get us the program's directory, even if we are frozen
-    using py2exe
-    """
+    获取程序的目录路径,即使使用了 py2exe 进行冻结打包也能正确获取。
 
+    返回值:
+    返回程序所在目录的Unicode编码路径字符串。
+    """
     try:
+        # 如果程序被py2exe冻结,则使用sys.executable获取路径;否则使用__file__获取
         _ = sys.executable if weAreFrozen() else __file__
     except NameError:
+        # 如果__file__未定义(在某些环境下可能发生),则使用inspect模块获取当前函数的文件路径
         _ = inspect.getsourcefile(modulePath)
 
+    # 获取_的目录路径,并转换为Unicode编码
     return getUnicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
 
 def checkEnvironment():
+    """
+    检查运行环境是否适合运行 sqlmap。
+
+    如果在检查过程中发现问题,则会记录错误信息并退出程序。
+    """
     try:
+        # 检查程序目录是否存在
         os.path.isdir(modulePath())
     except UnicodeEncodeError:
+        # 如果系统无法正确处理非ASCII路径,则记录错误信息并退出
         errMsg = "your system does not properly handle non-ASCII paths. "
         errMsg += "Please move the sqlmap's directory to the other location"
         logger.critical(errMsg)
         raise SystemExit
 
+    # 检查sqlmap的版本是否低于1.0,如果是,则说明运行环境有问题
     if LooseVersion(VERSION) < LooseVersion("1.0"):
         errMsg = "your runtime environment (e.g. PYTHONPATH) is "
         errMsg += "broken. Please make sure that you are not running "
@@ -130,68 +151,81 @@ def checkEnvironment():
         logger.critical(errMsg)
         raise SystemExit
 
-    # Patch for pip (import) environment
+    # 如果是通过pip安装的sqlmap,则需要对sys.modules进行一些修补操作
     if "sqlmap.sqlmap" in sys.modules:
         for _ in ("cmdLineOptions", "conf", "kb"):
+            # 将lib.core.data模块中的cmdLineOptions、conf、kb变量添加到全局变量中
             globals()[_] = getattr(sys.modules["lib.core.data"], _)
 
         for _ in ("SqlmapBaseException", "SqlmapShellQuitException", "SqlmapSilentQuitException", "SqlmapUserQuitException"):
+            # 将lib.core.exception模块中的异常类添加到全局变量中
             globals()[_] = getattr(sys.modules["lib.core.exception"], _)
-
 def main():
     """
-    Main function of sqlmap when running from command line.
+    当从命令行运行时,这是 sqlmap 的主函数。
     """
 
     try:
+        # 应用脏补丁和解析交叉引用
         dirtyPatches()
         resolveCrossReferences()
+        
+        # 检查运行环境并设置程序路径
         checkEnvironment()
         setPaths(modulePath())
         banner()
 
-        # Store original command line options for possible later restoration
+        # 解析命令行参数并更新全局配置
         args = cmdLineParser()
         cmdLineOptions.update(args.__dict__ if hasattr(args, "__dict__") else args)
         initOptions(cmdLineOptions)
 
+        # 如果有管道输入,则设置批量模式
         if checkPipedInput():
             conf.batch = True
 
+        # 如果配置了API,设置API日志和重定向标准输出和错误
         if conf.get("api"):
-            # heavy imports
+            # 延迟导入(重量级导入)
             from lib.utils.api import StdDbOut
             from lib.utils.api import setRestAPILog
 
-            # Overwrite system standard output and standard error to write
-            # to an IPC database
+            # 重定向标准输出和错误到IPC数据库
             sys.stdout = StdDbOut(conf.taskid, messagetype="stdout")
             sys.stderr = StdDbOut(conf.taskid, messagetype="stderr")
 
             setRestAPILog()
 
+        # 设置显示时间并显示法律声明和启动信息
         conf.showTime = True
         dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True)
         dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True)
 
+        # 初始化程序
         init()
 
+        # 如果没有设置更新所有选项,则执行后续操作
         if not conf.updateAll:
-            # Postponed imports (faster start)
+            # 延迟导入(更快的启动)
             if conf.smokeTest:
+                # 运行烟雾测试
                 from lib.core.testing import smokeTest
                 os._exitcode = 1 - (smokeTest() or 0)
             elif conf.vulnTest:
+                # 运行漏洞测试
                 from lib.core.testing import vulnTest
                 os._exitcode = 1 - (vulnTest() or 0)
             else:
+                # 启动sqlmap控制器
                 from lib.controller.controller import start
                 if conf.profile:
+                    # 如果设置了性能分析,则进行性能分析
                     from lib.core.profiling import profile
                     globals()["start"] = start
                     profile()
                 else:
                     try:
+                        # 如果设置了爬取深度和批量文件,则开始爬取
                         if conf.crawlDepth and conf.bulkFile:
                             targets = getFileItems(conf.bulkFile)
 
@@ -223,6 +257,7 @@ def main():
                     except Exception as ex:
                         os._exitcode = 1
 
+                        # 如果无法启动新线程,则记录错误信息并退出
                         if "can't start new thread" in getSafeExString(ex):
                             errMsg = "unable to start new threads. Please check OS (u)limits"
                             logger.critical(errMsg)
@@ -230,6 +265,7 @@ def main():
                         else:
                             raise
 
+    # 捕获并处理各种异常,记录错误信息并退出
     except SqlmapUserQuitException:
         if not conf.batch:
             errMsg = "user quit"
@@ -272,61 +308,73 @@ def main():
 
         os._exitcode = 255
 
+        # 如果异常信息中包含内存耗尽相关的消息,则记录内存耗尽错误并退出
         if any(_ in excMsg for _ in ("MemoryError", "Cannot allocate memory")):
             errMsg = "memory exhaustion detected"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含磁盘空间不足相关的消息,则记录磁盘空间错误并退出
         elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded", "Disk full while accessing")):
             errMsg = "no space left on output device"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含分页文件空间不足的消息,则记录分页文件空间错误并退出
         elif any(_ in excMsg for _ in ("The paging file is too small",)):
             errMsg = "no space left for paging file"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含权限拒绝和Metasploit相关的消息,则记录Metasploit权限错误并退出
         elif all(_ in excMsg for _ in ("Access is denied", "subprocess", "metasploit")):
             errMsg = "permission error occurred while running Metasploit"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含权限拒绝和metasploit相关的消息,则记录Metasploit权限错误并退出
         elif all(_ in excMsg for _ in ("Permission denied", "metasploit")):
             errMsg = "permission error occurred while using Metasploit"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含只读文件系统的消息,则记录只读文件系统错误并退出
         elif "Read-only file system" in excMsg:
             errMsg = "output device is mounted as read-only"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含系统资源不足的消息,则记录资源耗尽错误并退出
         elif "Insufficient system resources" in excMsg:
             errMsg = "resource exhaustion detected"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含磁盘I/O错误的消息,则记录I/O错误并退出
         elif "OperationalError: disk I/O error" in excMsg:
             errMsg = "I/O error on output device"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含URL违反BIDI规则的消息,则记录无效URL错误并退出
         elif "Violation of BIDI" in excMsg:
             errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含无效IPv6 URL的消息,则记录无效URL错误并退出
         elif "Invalid IPv6 URL" in excMsg:
             errMsg = "invalid URL ('%s')" % excMsg.strip().split('\n')[-1]
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含临时文件访问问题的消息,则记录临时文件访问错误并退出
         elif "_mkstemp_inner" in excMsg:
             errMsg = "there has been a problem while accessing temporary files"
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含无法写入临时目录的消息,则记录临时目录写入错误并退出
         elif any(_ in excMsg for _ in ("tempfile.mkdtemp", "tempfile.mkstemp", "tempfile.py")):
             errMsg = "unable to write to the temporary directory '%s'. " % tempfile.gettempdir()
             errMsg += "Please make sure that your disk is not full and "
@@ -335,131 +383,139 @@ def main():
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含权限拒绝的消息,则记录文件访问权限错误并退出
         elif "Permission denied: '" in excMsg:
             match = re.search(r"Permission denied: '([^']*)", excMsg)
             errMsg = "permission error occurred while accessing file '%s'" % match.group(1)
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含sqlalchemy包版本问题的消息,则记录sqlalchemy版本错误并退出
         elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")):
             errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) "
-            errMsg += "(Reference: 'https://qiita.com/tkprof/items/7d7b2d00df9c5f16fffe')"
+            # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含Python版本问题的消息,则记录Python版本错误并退出
         elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None:
             errMsg = "please upgrade the Python version (>= 3.5) "
-            errMsg += "(Reference: 'https://bugs.python.org/issue18183')"
+            # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。
             logger.critical(errMsg)
             raise SystemExit
 
+        # 如果异常信息中包含PyMySQL包版本问题的消息,则记录PyMySQL版本错误并退出
         elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")):
             errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) "
-            errMsg += "(Reference: 'https://github.com/PyMySQL/PyMySQL/issues/700')"
-            logger.critical(errMsg)
-            raise SystemExit
-
-        elif "must be pinned buffer, not bytearray" in excMsg:
-            errMsg = "error occurred at Python interpreter which "
-            errMsg += "is fixed in 2.7. Please update accordingly "
-            errMsg += "(Reference: 'https://bugs.python.org/issue8104')"
+            # 由于网络原因,无法解析提供的链接,可能是链接问题或网络问题,请检查链接的合法性并适当重试。
             logger.critical(errMsg)
             raise SystemExit
 
-        elif all(_ in excMsg for _ in ("OSError: [Errno 22] Invalid argument: '", "importlib")):
-            errMsg = "unable to read file '%s'" % extractRegexResult(r"OSError: \[Errno 22\] Invalid argument: '(?P<result>[^']+)", excMsg)
-            logger.critical(errMsg)
-            raise SystemExit
+        # 如果异常信息中包含Python解
 
-        elif "hash_randomization" in excMsg:
-            errMsg = "error occurred at Python interpreter which "
-            errMsg += "is fixed in 2.7.3. Please update accordingly "
-            errMsg += "(Reference: 'https://docs.python.org/2/library/sys.html')"
-            logger.critical(errMsg)
-            raise SystemExit
-
-        elif "AttributeError: unable to access item" in excMsg and re.search(r"3\.11\.\d+a", sys.version):
-            errMsg = "there is a known issue when sqlmap is run with ALPHA versions of Python 3.11. "
-            errMsg += "Please downgrade to some stable Python version"
-            logger.critical(errMsg)
-            raise SystemExit
-
-        elif all(_ in excMsg for _ in ("Resource temporarily unavailable", "os.fork()", "dictionaryAttack")):
-            errMsg = "there has been a problem while running the multiprocessing hash cracking. "
-            errMsg += "Please rerun with option '--threads=1'"
-            logger.critical(errMsg)
-            raise SystemExit
-
-        elif "can't start new thread" in excMsg:
-            errMsg = "there has been a problem while creating new thread instance. "
-            errMsg += "Please make sure that you are not running too many processes"
-            if not IS_WIN:
-                errMsg += " (or increase the 'ulimit -u' value)"
-            logger.critical(errMsg)
-            raise SystemExit
-
-        elif "can't allocate read lock" in excMsg:
-            errMsg = "there has been a problem in regular socket operation "
-            errMsg += "('%s')" % excMsg.strip().split('\n')[-1]
-            logger.critical(errMsg)
-            raise SystemExit
+        # 假设excMsg是一个包含异常信息的字符串变量
 
+        # 检查excMsg是否包含"pymysql"和"configparser"这两个字符串
         elif all(_ in excMsg for _ in ("pymysql", "configparser")):
+            # 如果都包含,则设置错误信息为检测到'pymsql'的错误初始化(使用了Python3的依赖)
             errMsg = "wrong initialization of 'pymsql' detected (using Python3 dependencies)"
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查excMsg是否包含"ntlm"、"socket.error, err"和"SyntaxError"这三个字符串
         elif all(_ in excMsg for _ in ("ntlm", "socket.error, err", "SyntaxError")):
+            # 如果都包含,则设置错误信息为检测到'python-ntlm'的错误初始化(使用了Python2的语法)
             errMsg = "wrong initialization of 'python-ntlm' detected (using Python2 syntax)"
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查excMsg是否包含"drda"和"to_bytes"这两个字符串
         elif all(_ in excMsg for _ in ("drda", "to_bytes")):
+            # 如果都包含,则设置错误信息为检测到'drda'的错误初始化(使用了Python3的语法)
             errMsg = "wrong initialization of 'drda' detected (using Python3 syntax)"
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
-
+        
+        # 检查excMsg是否包含特定的错误信息,即'WebSocket'对象没有'status'属性
         elif "'WebSocket' object has no attribute 'status'" in excMsg:
+            # 如果包含,则设置错误信息为检测到错误的websocket库
             errMsg = "wrong websocket library detected"
-            errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')"
+            # 添加参考链接到错误信息中
+            errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')" 
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查excMsg是否包含特定的错误信息,即初始化GUI界面时出现问题
         elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)):
+            # 如果包含,则设置错误信息为GUI界面初始化问题
             errMsg = "there has been a problem in initialization of GUI interface "
+            # 添加具体的错误信息到错误消息中
             errMsg += "('%s')" % excMsg.strip().split('\n')[-1]
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查excMsg是否包含特定的错误信息,即使用了不同版本的sqlmap文件
         elif any(_ in excMsg for _ in ("unable to access item 'liveTest'",)):
+            # 如果包含,则设置错误信息为检测到使用了不同版本的sqlmap文件
             errMsg = "detected usage of files from different versions of sqlmap"
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查errMsg是否包含特定的错误信息,即版本号相关的错误
         elif any(_ in errMsg for _ in (": 9.9.9#",)):
+            # 如果包含,则设置错误信息为一个简单的文本
             errMsg = "LOL xD"
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查是否设置了键盘中断的标记
         elif kb.get("dumpKeyboardInterrupt"):
+            # 如果设置了,则抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查excMsg是否包含特定的错误信息,即"Broken pipe"
         elif any(_ in excMsg for _ in ("Broken pipe",)):
+            # 如果包含,则直接抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查valid变量是否为False
         elif valid is False:
+            # 如果为False,则设置错误信息为代码校验失败
             errMsg = "code checksum failed (turning off automatic issue creation). "
             errMsg += "You should retrieve the latest development version from official GitHub "
             errMsg += "repository at '%s'" % GIT_PAGE
+            # 使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 打印空行
             print()
+            # 将错误信息输出到标准输出
             dataToStdout(excMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
+        # 检查errMsg和excMsg组合后是否包含特定的错误信息,即文件路径或特定参数
         elif any(_ in "%s\n%s" % (errMsg, excMsg) for _ in ("tamper/", "waf/", "--engagement-dojo")):
+            # 如果包含,则使用logger记录这个严重错误
             logger.critical(errMsg)
+            # 打印空行
             print()
+            # 将错误信息输出到标准输出
             dataToStdout(excMsg)
+            # 抛出SystemExit异常,导致程序退出
             raise SystemExit
 
         elif any(_ in excMsg for _ in ("ImportError", "ModuleNotFoundError", "<frozen", "Can't find file for module", "SAXReaderNotAvailable", "<built-in function compile> returned NULL without setting an exception", "source code string cannot contain null bytes", "No module named", "tp_name field", "module 'sqlite3' has no attribute 'OperationalError'")):
@@ -606,21 +662,31 @@ def main():
             conf.disableBanner = True
             main()
 
+# 检查是否是作为主模块运行,如果是,则执行以下代码
 if __name__ == "__main__":
     try:
+        # 尝试调用main函数
         main()
     except KeyboardInterrupt:
+        # 如果用户按下Ctrl+C(键盘中断),则捕获KeyboardInterrupt异常,但不执行任何操作(pass表示空操作)
         pass
     except SystemExit:
+        # 如果程序调用了sys.exit(),则重新抛出SystemExit异常,允许正常退出流程
         raise
     except:
+        # 捕获其他所有异常,并打印异常信息
         traceback.print_exc()
     finally:
-        # Reference: http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program
+        # 无论try块中的代码是否成功执行,都会执行finally块中的代码
+        # 参考:http://stackoverflow.com/questions/1635080/terminate-a-multi-thread-python-program
+        # 检查当前线程数量是否大于1(主线程和至少一个其他线程)
         if threading.active_count() > 1:
+            # 如果大于1,则调用os._exit强制退出程序,不进行清理操作
+            # getattr(os, "_exitcode", 0)用于获取os模块的_exitcode属性,如果不存在则默认为0
             os._exit(getattr(os, "_exitcode", 0))
         else:
+            # 如果只有主线程,则正常退出程序
             sys.exit(getattr(os, "_exitcode", 0))
 else:
-    # cancelling postponed imports (because of CI/CD checks)
-    __import__("lib.controller.controller")
+    # 如果不是作为主模块运行,则取消延迟导入(因为CI/CD检查)
+    __import__("lib.controller.controller")
\ No newline at end of file
diff --git a/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png b/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/class_diagram_classes_class_diagram.png differ
diff --git a/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png b/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/tamper_classes_tamper.png differ
diff --git a/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png b/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png
new file mode 100644
index 0000000..7278781
Binary files /dev/null and b/src/sqlmap-master/tamper/class_diagram/tamper_packages_tamper.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png
new file mode 100644
index 0000000..a1efc3f
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_classes_ansistrm.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png
new file mode 100644
index 0000000..6017f12
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/ansistrm_packages_ansistrm.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png
new file mode 100644
index 0000000..ae333d2
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_classes_beautifulsoup.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png
new file mode 100644
index 0000000..8061c87
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/beautifulsoup_packages_beautifulsoup.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png b/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png
new file mode 100644
index 0000000..e9a56cb
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/bottle_classes_bottle.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png b/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png
new file mode 100644
index 0000000..8242e92
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/bottle_packages_bottle.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png b/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png
new file mode 100644
index 0000000..08b6c01
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/chardet_classes_chardet.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png b/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png
new file mode 100644
index 0000000..570855c
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/chardet_packages_chardet.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png b/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png
new file mode 100644
index 0000000..dbb2fd1
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/clientform_classes_clientform.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png b/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png
new file mode 100644
index 0000000..8c9add4
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/clientform_packages_clientform.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png b/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png
new file mode 100644
index 0000000..e212382
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/colorama_classes_colorama.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png b/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png
new file mode 100644
index 0000000..93a133f
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/colorama_packages_colorama.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_classes_fcrypt.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png
new file mode 100644
index 0000000..a00060a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/fcrypt_packages_fcrypt.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png b/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/identywaf_classes_identywaf.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png b/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png
new file mode 100644
index 0000000..f39d923
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/identywaf_packages_identywaf.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png b/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png
new file mode 100644
index 0000000..d770bba
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/keepalive_classes_keepalive.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png b/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png
new file mode 100644
index 0000000..9d58587
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/keepalive_packages_keepalive.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png b/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png
new file mode 100644
index 0000000..f86b124
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/magic_classes_magic.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png b/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png
new file mode 100644
index 0000000..f9298b3
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/magic_packages_magic.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png b/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png
new file mode 100644
index 0000000..5c10f0f
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/multipart_classes_multipart.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png b/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png
new file mode 100644
index 0000000..072e924
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/multipart_packages_multipart.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png b/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png
new file mode 100644
index 0000000..1cd5229
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/odict_classes_odict.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png b/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png
new file mode 100644
index 0000000..34b7e4f
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/odict_packages_odict.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_classes_prettyprint.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png
new file mode 100644
index 0000000..a9fca5a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/prettyprint_packages_prettyprint.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png b/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png
new file mode 100644
index 0000000..e7753cc
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/pydes_classes_pydes.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png b/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png
new file mode 100644
index 0000000..246230a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/pydes_packages_pydes.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png b/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png
new file mode 100644
index 0000000..c954792
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/six_classes_six.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png b/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png
new file mode 100644
index 0000000..b8d3c7d
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/socks_classes_socks.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png b/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png
new file mode 100644
index 0000000..1c5f9c4
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/socks_packages_socks.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png b/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png
new file mode 100644
index 0000000..bcaf83a
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/termcolor_classes_termcolor.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png b/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png
new file mode 100644
index 0000000..91df5e1
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/termcolor_packages_termcolor.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png
new file mode 100644
index 0000000..f69e17b
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_classes_wininetpton.png differ
diff --git a/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png
new file mode 100644
index 0000000..165aa31
Binary files /dev/null and b/src/sqlmap-master/thirdparty/class_diagram/wininetpton_packages_wininetpton.png differ
diff --git a/src/sqlmap-master/thirdparty/socks/socks.py b/src/sqlmap-master/thirdparty/socks/socks.py
index 4005cab..af914a4 100644
--- a/src/sqlmap-master/thirdparty/socks/socks.py
+++ b/src/sqlmap-master/thirdparty/socks/socks.py
@@ -121,6 +121,7 @@ def unwrapmodule(module):
     module.socket.socket = _orgsocket
     module.socket.create_connection = _orgcreateconnection
 
+
 class socksocket(socket.socket):
     """socksocket([family[, type[, proto]]]) -> socket object
     Open a SOCKS enabled socket. The parameters are the same as
@@ -129,11 +130,17 @@ class socksocket(socket.socket):
     """
 
     def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None):
+        # 初始化父类 socket
         _orgsocket.__init__(self, family, type, proto, _sock)
+
+        # 根据默认代理设置代理
         if _defaultproxy != None:
             self.__proxy = _defaultproxy
         else:
+            # 初始化代理信息,如果没有默认代理则设为空元组
             self.__proxy = (None, None, None, None, None, None)
+
+        # 用于保存代理关联的本地socket信息
         self.__proxysockname = None
         self.__proxypeername = None
 
@@ -142,121 +149,111 @@ class socksocket(socket.socket):
         Receive EXACTLY the number of bytes requested from the socket.
         Blocks until the required number of bytes have been received.
         """
+        # 从socket接收指定字节数数据
         data = self.recv(count)
+        # 当接收的数据少于请求的字节数时继续接收
         while len(data) < count:
-            d = self.recv(count-len(data))
-            if not d: raise GeneralProxyError((0, "connection closed unexpectedly"))
-            data = data + d
+            d = self.recv(count - len(data))
+            if not d:
+                raise GeneralProxyError((0, "connection closed unexpectedly"))  # 如果连接关闭则抛出异常
+            data = data + d  # 累加接收到的数据
         return data
 
     def setproxy(self, proxytype=None, addr=None, port=None, rdns=True, username=None, password=None):
         """setproxy(proxytype, addr[, port[, rdns[, username[, password]]]])
         Sets the proxy to be used.
-        proxytype -    The type of the proxy to be used. Three types
-                are supported: PROXY_TYPE_SOCKS4 (including socks4a),
-                PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP
-        addr -        The address of the server (IP or DNS).
-        port -        The port of the server. Defaults to 1080 for SOCKS
-                servers and 8080 for HTTP proxy servers.
-        rdns -        Should DNS queries be preformed on the remote side
-                (rather than the local side). The default is True.
-                Note: This has no effect with SOCKS4 servers.
-        username -    Username to authenticate with to the server.
-                The default is no authentication.
-        password -    Password to authenticate with to the server.
-                Only relevant when username is also provided.
         """
+        # 设置代理类型、地址、端口等参数
         self.__proxy = (proxytype, addr, port, rdns, username, password)
 
     def __negotiatesocks5(self, destaddr, destport):
         """__negotiatesocks5(self,destaddr,destport)
         Negotiates a connection through a SOCKS5 server.
         """
-        # First we'll send the authentication packages we support.
-        if (self.__proxy[4]!=None) and (self.__proxy[5]!=None):
-            # The username/password details were supplied to the
-            # setproxy method so we support the USERNAME/PASSWORD
-            # authentication (in addition to the standard none).
-            self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02))
+        # 发送支持的认证方法
+        if (self.__proxy[4] != None) and (self.__proxy[5] != None):
+            # 如果提供了用户名和密码,则支持用户名/密码认证
+            self.sendall(struct.pack('BBBB', 0x05, 0x02, 0x00, 0x02))  # 0x02 代表用户名/密码认证
         else:
-            # No username/password were entered, therefore we
-            # only support connections with no authentication.
-            self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00))
-        # We'll receive the server's response to determine which
-        # method was selected
+            # 仅支持无认证连接
+            self.sendall(struct.pack('BBB', 0x05, 0x01, 0x00))  # 0x01 代表无认证
+
+        # 接收服务器的响应以确定选定的身份验证方法
         chosenauth = self.__recvall(2)
         if chosenauth[0:1] != b'\x05':
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
-        # Check the chosen authentication method
+            raise GeneralProxyError((1, _generalerrors[1]))  # 无效的协议版本
+
+        # 检查所选的身份验证方法
         if chosenauth[1:2] == b'\x00':
-            # No authentication is required
+            # 无需身份验证
             pass
         elif chosenauth[1:2] == b'\x02':
-            # Okay, we need to perform a basic username/password
-            # authentication.
-            self.sendall(b'\x01' + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr(len(self.__proxy[5])).encode() + self.__proxy[5].encode())
-            authstat = self.__recvall(2)
+            # 需要进行用户名/密码身份验证
+            self.sendall(b'\x01' + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr(
+                len(self.__proxy[5])).encode() + self.__proxy[5].encode())
+            authstat = self.__recvall(2)  # 接收身份验证状态
             if authstat[0:1] != b'\x01':
-                # Bad response
                 self.close()
-                raise GeneralProxyError((1, _generalerrors[1]))
+                raise GeneralProxyError((1, _generalerrors[1]))  # 无效的认证响应
             if authstat[1:2] != b'\x00':
-                # Authentication failed
                 self.close()
-                raise Socks5AuthError((3, _socks5autherrors[3]))
-            # Authentication succeeded
+                raise Socks5AuthError((3, _socks5autherrors[3]))  # 身份验证失败
         else:
-            # Reaching here is always bad
+            # 非法的身份验证方法
             self.close()
             if chosenauth[1:2] == b'\xff':
-                raise Socks5AuthError((2, _socks5autherrors[2]))
+                raise Socks5AuthError((2, _socks5autherrors[2]))  # 不支持的身份验证
             else:
                 raise GeneralProxyError((1, _generalerrors[1]))
-        # Now we can request the actual connection
-        req = struct.pack('BBB', 0x05, 0x01, 0x00)
-        # If the given destination address is an IP address, we'll
-        # use the IPv4 address request even if remote resolving was specified.
+
+        # 请求实际连接
+        req = struct.pack('BBB', 0x05, 0x01, 0x00)  # 0x01 表示连接请求
         try:
+            # 尝试将目标地址作为IP地址处理
             ipaddr = socket.inet_aton(destaddr)
-            req = req + b'\x01' + ipaddr
+            req = req + b'\x01' + ipaddr  # IPv4地址请求
         except socket.error:
-            # Well it's not an IP number,  so it's probably a DNS name.
-            if self.__proxy[3]:
-                # Resolve remotely
+            # 目标地址不是IP地址,可能是DNS名称
+            if self.__proxy[3]:  # 检查是否需要远程解析
                 ipaddr = None
-                req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + (destaddr if isinstance(destaddr, bytes) else destaddr.encode())
+                req = req + chr(0x03).encode() + chr(len(destaddr)).encode() + (
+                    destaddr if isinstance(destaddr, bytes) else destaddr.encode())
             else:
-                # Resolve locally
+                # 本地解析
                 ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
                 req = req + chr(0x01).encode() + ipaddr
-        req = req + struct.pack(">H", destport)
-        self.sendall(req)
-        # Get the response
+        req = req + struct.pack(">H", destport)  # 添加目标端口
+        self.sendall(req)  # 发送请求
+
+        # 获取响应
         resp = self.__recvall(4)
         if resp[0:1] != chr(0x05).encode():
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
+            raise GeneralProxyError((1, _generalerrors[1]))  # 协议错误
         elif resp[1:2] != chr(0x00).encode():
-            # Connection failed
+            # 连接失败
             self.close()
-            if ord(resp[1:2])<=8:
+            if ord(resp[1:2]) <= 8:
                 raise Socks5Error((ord(resp[1:2]), _socks5errors[ord(resp[1:2])]))
             else:
                 raise Socks5Error((9, _socks5errors[9]))
-        # Get the bound address/port
+
+        # 解析绑定地址/端口
         elif resp[3:4] == chr(0x01).encode():
-            boundaddr = self.__recvall(4)
+            boundaddr = self.__recvall(4)  # IPv4绑定地址
         elif resp[3:4] == chr(0x03).encode():
-            resp = resp + self.recv(1)
-            boundaddr = self.__recvall(ord(resp[4:5]))
+            resp = resp + self.recv(1)  # 读取后续字节
+            boundaddr = self.__recvall(ord(resp[4:5]))  # DNS名
         else:
             self.close()
-            raise GeneralProxyError((1,_generalerrors[1]))
+            raise GeneralProxyError((1, _generalerrors[1]))
+
+        # 获取绑定端口
         boundport = struct.unpack(">H", self.__recvall(2))[0]
-        self.__proxysockname = (boundaddr, boundport)
+        self.__proxysockname = (boundaddr, boundport)  # 保存绑定的socket信息
         if ipaddr != None:
-            self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
+            self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)  # 保存peer名称
         else:
             self.__proxypeername = (destaddr, destport)
 
@@ -264,135 +261,153 @@ class socksocket(socket.socket):
         """getsockname() -> address info
         Returns the bound IP address and port number at the proxy.
         """
-        return self.__proxysockname
+        return self.__proxysockname  # 返回代理的socket信息
 
     def getproxypeername(self):
         """getproxypeername() -> address info
         Returns the IP and port number of the proxy.
         """
-        return _orgsocket.getpeername(self)
+        return _orgsocket.getpeername(self)  # 返回代理的peer信息
 
     def getpeername(self):
         """getpeername() -> address info
         Returns the IP address and port number of the destination
         machine (note: getproxypeername returns the proxy)
         """
-        return self.__proxypeername
+        return self.__proxypeername  # 返回目标机器的peer名称
 
-    def __negotiatesocks4(self,destaddr,destport):
+    def __negotiatesocks4(self, destaddr, destport):
         """__negotiatesocks4(self,destaddr,destport)
         Negotiates a connection through a SOCKS4 server.
         """
-        # Check if the destination address provided is an IP address
+        # 检查目标地址是否为IP地址
         rmtrslv = False
         try:
             ipaddr = socket.inet_aton(destaddr)
         except socket.error:
-            # It's a DNS name. Check where it should be resolved.
+            # 目标是DNS名称, 检查是否应进行远程解析
             if self.__proxy[3]:
-                ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)
+                ipaddr = struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)  # 默认IP地址
                 rmtrslv = True
             else:
-                ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))
-        # Construct the request packet
-        req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr
-        # The username parameter is considered userid for SOCKS4
+                ipaddr = socket.inet_aton(socket.gethostbyname(destaddr))  # 本地解析
+
+        # 构造请求报文
+        req = struct.pack(">BBH", 0x04, 0x01, destport) + ipaddr  # SOCKS4 请求
+        # 用户名参数视为userid
         if self.__proxy[4] != None:
             req = req + self.__proxy[4]
-        req = req + chr(0x00).encode()
-        # DNS name if remote resolving is required
-        # NOTE: This is actually an extension to the SOCKS4 protocol
-        # called SOCKS4A and may not be supported in all cases.
+        req = req + chr(0x00).encode()  # 请求结束
+
+        # 需要远程解析的情况下使用DNS名称
         if rmtrslv:
-            req = req + destaddr + chr(0x00).encode()
-        self.sendall(req)
-        # Get the response from the server
+            req = req + destaddr + chr(0x00).encode()  # SOCKS4A扩展
+        self.sendall(req)  # 发送请求
+
+        # 获取服务器响应
         resp = self.__recvall(8)
         if resp[0:1] != chr(0x00).encode():
-            # Bad data
+            # 出现错误
             self.close()
-            raise GeneralProxyError((1,_generalerrors[1]))
+            raise GeneralProxyError((1, _generalerrors[1]))  # 无效数据
         if resp[1:2] != chr(0x5A).encode():
-            # Server returned an error
+            # 服务器返回错误
             self.close()
             if ord(resp[1:2]) in (91, 92, 93):
                 self.close()
-                raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90]))
+                raise Socks4Error((ord(resp[1:2]), _socks4errors[ord(resp[1:2]) - 90]))  # 处理错误代码
             else:
-                raise Socks4Error((94, _socks4errors[4]))
-        # Get the bound address/port
-        self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])
+                raise Socks4Error((94, _socks4errors[4]))  # 一般性错误
+
+        # 获取绑定的地址和端口
+        self.__proxysockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0])  # 保存绑定信息
         if rmtrslv != None:
-            self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)
+            self.__proxypeername = (socket.inet_ntoa(ipaddr), destport)  # 目标地址
         else:
-            self.__proxypeername = (destaddr, destport)
+            self.__proxypeername = (destaddr, destport)  # 目标地址
 
     def __negotiatehttp(self, destaddr, destport):
         """__negotiatehttp(self,destaddr,destport)
         Negotiates a connection through an HTTP server.
         """
-        # If we need to resolve locally, we do this now
+        # 本地解析
         if not self.__proxy[3]:
             addr = socket.gethostbyname(destaddr)
         else:
             addr = destaddr
-        self.sendall(("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode())
-        # We read the response until we get the string "\r\n\r\n"
+
+        # 发送HTTP的CONNECT请求
+        self.sendall(
+            ("CONNECT " + addr + ":" + str(destport) + " HTTP/1.1\r\n" + "Host: " + destaddr + "\r\n\r\n").encode())
+
+        # 读取响应直到遇到"\r\n\r\n"
         resp = self.recv(1)
         while resp.find("\r\n\r\n".encode()) == -1:
             resp = resp + self.recv(1)
-        # We just need the first line to check if the connection
-        # was successful
+
+        # 仅需第一行检查连接是否成功
         statusline = resp.splitlines()[0].split(" ".encode(), 2)
         if statusline[0] not in ("HTTP/1.0".encode(), "HTTP/1.1".encode()):
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
+            raise GeneralProxyError((1, _generalerrors[1]))  # 无效的HTTP协议
         try:
-            statuscode = int(statusline[1])
+            statuscode = int(statusline[1])  # 获取状态码
         except ValueError:
             self.close()
-            raise GeneralProxyError((1, _generalerrors[1]))
+            raise GeneralProxyError((1, _generalerrors[1]))  # 状态码无效
         if statuscode != 200:
             self.close()
-            raise HTTPError((statuscode, statusline[2]))
-        self.__proxysockname = ("0.0.0.0", 0)
-        self.__proxypeername = (addr, destport)
+            raise HTTPError((statuscode, statusline[2]))  # 显示状态码错误
+
+        # 连接成功后的代理信息
+        self.__proxysockname = ("0.0.0.0", 0)  # 绑定在0.0.0.0
+        self.__proxypeername = (addr, destport)  # 保存peer信息
 
     def connect(self, destpair):
-        """connect(self, despair)
+        """connect(self, destpair)
         Connects to the specified destination through a proxy.
-        destpar - A tuple of the IP/DNS address and the port number.
+        destpair - A tuple of the IP/DNS address and the port number.
         (identical to socket's connect).
         To select the proxy server use setproxy().
         """
-        # Do a minimal input check first
-        if (not type(destpair) in (list,tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (type(destpair[1]) != int):
+        # 校验输入参数
+        if (not type(destpair) in (list, tuple)) or (len(destpair) < 2) or (type(destpair[0]) != type('')) or (
+                type(destpair[1]) != int):
             raise GeneralProxyError((5, _generalerrors[5]))
+
+        # 根据代理类型选择相应的握手协议
         if self.__proxy[0] == PROXY_TYPE_SOCKS5:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
-                portnum = 1080
-            _orgsocket.connect(self, (self.__proxy[1], portnum))
-            self.__negotiatesocks5(destpair[0], destpair[1])
+                portnum = 1080  # 默认端口
+
+            _orgsocket.connect(self, (self.__proxy[1], portnum))  # 连接到代理
+            self.__negotiatesocks5(destpair[0], destpair[1])  # 握手
+
         elif self.__proxy[0] == PROXY_TYPE_SOCKS4:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
-                portnum = 1080
-            _orgsocket.connect(self,(self.__proxy[1], portnum))
-            self.__negotiatesocks4(destpair[0], destpair[1])
+                portnum = 1080  # 默认端口
+
+            _orgsocket.connect(self, (self.__proxy[1], portnum))  # 连接到代理
+            self.__negotiatesocks4(destpair[0], destpair[1])  # 握手
+
         elif self.__proxy[0] == PROXY_TYPE_HTTP:
             if self.__proxy[2] != None:
                 portnum = self.__proxy[2]
             else:
-                portnum = 8080
-            _orgsocket.connect(self,(self.__proxy[1], portnum))
-            self.__negotiatehttp(destpair[0], destpair[1])
+                portnum = 8080  # 默认端口
+
+            _orgsocket.connect(self, (self.__proxy[1], portnum))  # 连接到代理
+            self.__negotiatehttp(destpair[0], destpair[1])  # 握手
+
         elif self.__proxy[0] == None:
+            # 没有代理时直接连接目标
             _orgsocket.connect(self, (destpair[0], destpair[1]))
         else:
-            raise GeneralProxyError((4, _generalerrors[4]))
+            raise GeneralProxyError((4, _generalerrors[4]))  # 不支持的代理类型
 
 def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
                     source_address=None):
diff --git a/src/sqlmap-master/thirdparty/termcolor/termcolor.py b/src/sqlmap-master/thirdparty/termcolor/termcolor.py
index ddea6dd..2ba380b 100644
--- a/src/sqlmap-master/thirdparty/termcolor/termcolor.py
+++ b/src/sqlmap-master/thirdparty/termcolor/termcolor.py
@@ -79,12 +79,14 @@ COLORS = dict(
             ))
         )
 
+# 添加亮色到 COLORS 字典
 COLORS.update(dict(("light%s" % color, COLORS[color] + 60) for color in COLORS))
 
-# Reference: https://misc.flogisoft.com/bash/tip_colors_and_formatting
-COLORS["lightgrey"] = 37
-COLORS["darkgrey"] = 90
+# 带有参考的颜色定义
+COLORS["lightgrey"] = 37  # 亮灰色
+COLORS["darkgrey"] = 90   # 深灰色
 
+# 定义重置颜色的转义序列
 RESET = '\033[0m'
 
 
@@ -104,34 +106,37 @@ def colored(text, color=None, on_color=None, attrs=None):
         colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink'])
         colored('Hello, World!', 'green')
     """
+    # 检查环境变量,以决定是否支持 ANSI 颜色
     if os.getenv('ANSI_COLORS_DISABLED') is None:
-        fmt_str = '\033[%dm%s'
+        fmt_str = '\033[%dm%s'  # ANSI 格式化字符串
         if color is not None:
-            text = fmt_str % (COLORS[color], text)
+            text = fmt_str % (COLORS[color], text)  # 将文本颜色应用于文本
 
         if on_color is not None:
-            text = fmt_str % (HIGHLIGHTS[on_color], text)
+            text = fmt_str % (HIGHLIGHTS[on_color], text)  # 将背景颜色应用于文本
 
         if attrs is not None:
             for attr in attrs:
-                text = fmt_str % (ATTRIBUTES[attr], text)
+                text = fmt_str % (ATTRIBUTES[attr], text)  # 应用文本属性
 
-        text += RESET
+        text += RESET  # 重置颜色到默认值
     return text
 
 
 def cprint(text, color=None, on_color=None, attrs=None, **kwargs):
-    """Print colorize text.
+    """打印带颜色的文本。
 
-    It accepts arguments of print function.
+    支持 print 函数的所有参数。
     """
-
-    print((colored(text, color, on_color, attrs)), **kwargs)
+    print((colored(text, color, on_color, attrs)), **kwargs)  # 调用 colored 函数并进行打印
 
 
 if __name__ == '__main__':
-    print('Current terminal type: %s' % os.getenv('TERM'))
+    # 用于测试的主模块
+    print('Current terminal type: %s' % os.getenv('TERM'))  # 打印当前终端类型
     print('Test basic colors:')
+
+    # 测试基本颜色
     cprint('Grey color', 'grey')
     cprint('Red color', 'red')
     cprint('Green color', 'green')
@@ -143,6 +148,7 @@ if __name__ == '__main__':
     print(('-' * 78))
 
     print('Test highlights:')
+    # 测试背景高亮
     cprint('On grey color', on_color='on_grey')
     cprint('On red color', on_color='on_red')
     cprint('On green color', on_color='on_green')
@@ -154,6 +160,7 @@ if __name__ == '__main__':
     print('-' * 78)
 
     print('Test attributes:')
+    # 测试文本属性
     cprint('Bold grey color', 'grey', attrs=['bold'])
     cprint('Dark red color', 'red', attrs=['dark'])
     cprint('Underline green color', 'green', attrs=['underline'])
@@ -161,13 +168,12 @@ if __name__ == '__main__':
     cprint('Reversed blue color', 'blue', attrs=['reverse'])
     cprint('Concealed Magenta color', 'magenta', attrs=['concealed'])
     cprint('Bold underline reverse cyan color', 'cyan',
-            attrs=['bold', 'underline', 'reverse'])
+           attrs=['bold', 'underline', 'reverse'])
     cprint('Dark blink concealed white color', 'white',
-            attrs=['dark', 'blink', 'concealed'])
+           attrs=['dark', 'blink', 'concealed'])
     print(('-' * 78))
 
     print('Test mixing:')
-    cprint('Underline red on grey color', 'red', 'on_grey',
-            ['underline'])
-    cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
-
+    # 测试混合使用颜色和属性
+    cprint('Underline red on grey color', 'red', 'on_grey', ['underline'])
+    cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
\ No newline at end of file
diff --git a/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py b/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py
index 50ae621..cfe5b3b 100644
--- a/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py
+++ b/src/sqlmap-master/thirdparty/wininetpton/win_inet_pton.py
@@ -9,30 +9,51 @@ import ctypes
 import os
 
 
+# 定义 sockaddr 结构体,以便与底层 socket API 交互
 class sockaddr(ctypes.Structure):
-    _fields_ = [("sa_family", ctypes.c_short),
-                ("__pad1", ctypes.c_ushort),
-                ("ipv4_addr", ctypes.c_byte * 4),
-                ("ipv6_addr", ctypes.c_byte * 16),
-                ("__pad2", ctypes.c_ulong)]
+    _fields_ = [
+        ("sa_family", ctypes.c_short),  # 地址族,例如 AF_INET 或 AF_INET6
+        ("__pad1", ctypes.c_ushort),  # 填充字段用于对齐
+        ("ipv4_addr", ctypes.c_byte * 4),  # IPv4 地址(4 字节)
+        ("ipv6_addr", ctypes.c_byte * 16),  # IPv6 地址(16 字节)
+        ("__pad2", ctypes.c_ulong)  # 额外填充字段
+    ]
 
+
+# 检测是否在 Windows 平台上,并加载相应的 Windows socket 函数
 if hasattr(ctypes, 'windll'):
-    WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA
-    WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA
+    WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA  # 字符串转换为地址
+    WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA  # 地址转换为字符串
 else:
     def not_windows():
         raise SystemError(
             "Invalid platform. ctypes.windll must be available."
         )
-    WSAStringToAddressA = not_windows
-    WSAAddressToStringA = not_windows
+
+
+    WSAStringToAddressA = not_windows  # 非 Windows 平台时的占位符
+    WSAAddressToStringA = not_windows  # 非 Windows 平台时的占位符
 
 
 def inet_pton(address_family, ip_string):
-    addr = sockaddr()
-    addr.sa_family = address_family
-    addr_size = ctypes.c_int(ctypes.sizeof(addr))
+    """
+    Convert an IP address from text to binary format.
+
+    Args:
+        address_family: The address family (AF_INET for IPv4 or AF_INET6 for IPv6).
+        ip_string: The IP address in string form (e.g., "192.168.1.1").
+
+    Returns:
+        A packed binary representation of the IP address.
 
+    Raises:
+        socket.error: If the conversion fails.
+    """
+    addr = sockaddr()  # 创建 sockaddr 实例
+    addr.sa_family = address_family  # 设置地址族
+    addr_size = ctypes.c_int(ctypes.sizeof(addr))  # 地址结构的大小
+
+    # 调用 WSAStringToAddressA 将字符串 IP 转换为二进制地址
     if WSAStringToAddressA(
             ip_string,
             address_family,
@@ -40,34 +61,50 @@ def inet_pton(address_family, ip_string):
             ctypes.byref(addr),
             ctypes.byref(addr_size)
     ) != 0:
-        raise socket.error(ctypes.FormatError())
+        raise socket.error(ctypes.FormatError())  # 转换失败时抛出异常
 
+    # 根据地址族返回相应的打包 IP 地址
     if address_family == socket.AF_INET:
-        return ctypes.string_at(addr.ipv4_addr, 4)
+        return ctypes.string_at(addr.ipv4_addr, 4)  # IPv4 地址
     if address_family == socket.AF_INET6:
-        return ctypes.string_at(addr.ipv6_addr, 16)
+        return ctypes.string_at(addr.ipv6_addr, 16)  # IPv6 地址
 
-    raise socket.error('unknown address family')
+    raise socket.error('unknown address family')  # 抛出未知地址族的异常
 
 
 def inet_ntop(address_family, packed_ip):
-    addr = sockaddr()
-    addr.sa_family = address_family
-    addr_size = ctypes.c_int(ctypes.sizeof(addr))
-    ip_string = ctypes.create_string_buffer(128)
-    ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))
+    """
+    Convert a binary IP address to its text representation.
+
+    Args:
+        address_family: The address family (AF_INET for IPv4 or AF_INET6 for IPv6).
+        packed_ip: The packed binary IP address.
+
+    Returns:
+        The IP address in string form.
 
+    Raises:
+        socket.error: If the conversion fails.
+    """
+    addr = sockaddr()  # 创建 sockaddr 实例
+    addr.sa_family = address_family  # 设置地址族
+    addr_size = ctypes.c_int(ctypes.sizeof(addr))  # 地址结构的大小
+    ip_string = ctypes.create_string_buffer(128)  # 用于存储 IP 字符串
+    ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))  # 字符串大小
+
+    # 根据地址族填充 sockaddr 结构
     if address_family == socket.AF_INET:
         if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr):
-            raise socket.error('packed IP wrong length for inet_ntoa')
-        ctypes.memmove(addr.ipv4_addr, packed_ip, 4)
+            raise socket.error('packed IP wrong length for inet_ntoa')  # IPv4 地址长度错误
+        ctypes.memmove(addr.ipv4_addr, packed_ip, 4)  # 复制 IPv4 地址
     elif address_family == socket.AF_INET6:
         if len(packed_ip) != ctypes.sizeof(addr.ipv6_addr):
-            raise socket.error('packed IP wrong length for inet_ntoa')
-        ctypes.memmove(addr.ipv6_addr, packed_ip, 16)
+            raise socket.error('packed IP wrong length for inet_ntoa')  # IPv6 地址长度错误
+        ctypes.memmove(addr.ipv6_addr, packed_ip, 16)  # 复制 IPv6 地址
     else:
-        raise socket.error('unknown address family')
+        raise socket.error('unknown address family')  # 抛出未知地址族的异常
 
+    # 调用 WSAAddressToStringA 将二进制地址转换为字符串
     if WSAAddressToStringA(
             ctypes.byref(addr),
             addr_size,
@@ -75,11 +112,12 @@ def inet_ntop(address_family, packed_ip):
             ip_string,
             ctypes.byref(ip_string_size)
     ) != 0:
-        raise socket.error(ctypes.FormatError())
+        raise socket.error(ctypes.FormatError())  # 转换失败时抛出异常
+
+    return ip_string[:ip_string_size.value - 1]  # 返回字符串表示形式,移除尾部的空字符
 
-    return ip_string[:ip_string_size.value - 1]
 
-# Adding our two functions to the socket library
+# 如果在 Windows 平台,将自定义的函数添加到 socket 库中
 if os.name == 'nt':
-    socket.inet_pton = inet_pton
-    socket.inet_ntop = inet_ntop
+    socket.inet_pton = inet_pton  # 添加 inet_pton 函数
+    socket.inet_ntop = inet_ntop  # 添加 inet_ntop 函数
\ No newline at end of file