From 138eb2afc605f39ecbd62ba56908a65e355c619f Mon Sep 17 00:00:00 2001
From: Warmlight <344053630@qq.com>
Date: Mon, 13 Jan 2025 00:39:29 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=89=B9=E6=B3=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/sqlmap-master/lib/core/datatype.py        | 207 +++++++-------
 .../plugins/dbms/mssqlserver/fingerprint.py   | 195 ++++++-------
 .../plugins/dbms/vertica/fingerprint.py       | 123 +++++----
 src/sqlmap-master/plugins/generic/custom.py   | 199 ++++++-------
 src/sqlmap-master/plugins/generic/misc.py     | 261 +++++++++---------
 5 files changed, 488 insertions(+), 497 deletions(-)

diff --git a/src/sqlmap-master/lib/core/datatype.py b/src/sqlmap-master/lib/core/datatype.py
index 866b114..9638f0d 100644
--- a/src/sqlmap-master/lib/core/datatype.py
+++ b/src/sqlmap-master/lib/core/datatype.py
@@ -5,13 +5,15 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-import copy
-import threading
-import types
+# 导入必要的模块
+import copy # 导入 copy 模块,用于对象复制
+import threading # 导入 threading 模块,用于线程同步
+import types # 导入 types 模块,用于类型判断
 
-from thirdparty.odict import OrderedDict
-from thirdparty.six.moves import collections_abc as _collections
+from thirdparty.odict import OrderedDict # 导入 thirdparty 中的 OrderedDict 类,用于实现有序字典
+from thirdparty.six.moves import collections_abc as _collections # 导入 six 库中的 collections_abc 模块,用于抽象集合类
 
+# 定义 AttribDict 类,继承自 dict,允许以属性方式访问字典成员
 class AttribDict(dict):
     """
     This class defines the dictionary with added capability to access members as attributes
@@ -22,20 +24,20 @@ class AttribDict(dict):
     1
     """
 
+    # 初始化方法,接受一个字典 indict,一个属性 attribute 和一个布尔值 keycheck
     def __init__(self, indict=None, attribute=None, keycheck=True):
-        if indict is None:
+        if indict is None: # 如果 indict 为空,初始化为空字典
             indict = {}
 
-        # Set any attributes here - before initialisation
-        # these remain as normal attributes
+        # 设置属性,这些属性在初始化前是普通属性
         self.attribute = attribute
         self.keycheck = keycheck
-        dict.__init__(self, indict)
-        self.__initialised = True
+        dict.__init__(self, indict) # 调用 dict 的初始化方法
+        self.__initialised = True # 设置初始化完成标志
 
-        # After initialisation, setting attributes
-        # is the same as setting an item
+        # 在初始化之后,设置属性与设置字典项相同
 
+    # 定义 __getattr__ 方法,用于获取属性
     def __getattr__(self, item):
         """
         Maps values to attributes
@@ -43,89 +45,95 @@ class AttribDict(dict):
         """
 
         try:
-            return self.__getitem__(item)
-        except KeyError:
-            if self.keycheck:
-                raise AttributeError("unable to access item '%s'" % item)
-            else:
-                return None
-
+            return self.__getitem__(item) # 尝试获取字典项
+        except KeyError: # 如果字典中不存在此键
+            if self.keycheck: # 如果 keycheck 为 True
+                raise AttributeError("unable to access item '%s'" % item) # 抛出属性错误
+            else: # 如果 keycheck 为 False
+                return None # 返回 None
+
+    # 定义 __delattr__ 方法,用于删除属性
     def __delattr__(self, item):
         """
         Deletes attributes
         """
 
         try:
-            return self.pop(item)
-        except KeyError:
-            if self.keycheck:
-                raise AttributeError("unable to access item '%s'" % item)
-            else:
-                return None
-
+            return self.pop(item) # 尝试从字典中删除项
+        except KeyError: # 如果字典中不存在此键
+            if self.keycheck: # 如果 keycheck 为 True
+                raise AttributeError("unable to access item '%s'" % item) # 抛出属性错误
+            else: # 如果 keycheck 为 False
+                return None # 返回 None
+
+    # 定义 __setattr__ 方法,用于设置属性
     def __setattr__(self, item, value):
         """
         Maps attributes to values
         Only if we are initialised
         """
 
-        # This test allows attributes to be set in the __init__ method
+        # 在初始化方法中允许设置属性
         if "_AttribDict__initialised" not in self.__dict__:
             return dict.__setattr__(self, item, value)
 
-        # Any normal attributes are handled normally
+        # 正常处理普通属性
         elif item in self.__dict__:
             dict.__setattr__(self, item, value)
 
-        else:
+        else: # 其他情况,将属性映射到字典项
             self.__setitem__(item, value)
 
+    # 定义 __getstate__ 方法,用于支持序列化
     def __getstate__(self):
         return self.__dict__
 
+    # 定义 __setstate__ 方法,用于支持反序列化
     def __setstate__(self, dict):
         self.__dict__ = dict
 
+    # 定义 __deepcopy__ 方法,用于深拷贝
     def __deepcopy__(self, memo):
-        retVal = self.__class__()
-        memo[id(self)] = retVal
+        retVal = self.__class__() # 创建一个新实例
+        memo[id(self)] = retVal # 将新实例添加到 memo 中
 
-        for attr in dir(self):
-            if not attr.startswith('_'):
-                value = getattr(self, attr)
-                if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)):
-                    setattr(retVal, attr, copy.deepcopy(value, memo))
+        for attr in dir(self): # 遍历所有属性
+            if not attr.startswith('_'): # 忽略私有属性
+                value = getattr(self, attr) # 获取属性值
+                if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)): # 忽略内置函数、函数和方法
+                    setattr(retVal, attr, copy.deepcopy(value, memo)) # 深拷贝属性值
 
-        for key, value in self.items():
-            retVal.__setitem__(key, copy.deepcopy(value, memo))
+        for key, value in self.items(): # 遍历所有字典项
+            retVal.__setitem__(key, copy.deepcopy(value, memo)) # 深拷贝字典项
 
-        return retVal
+        return retVal # 返回深拷贝后的实例
 
+# 定义 InjectionDict 类,继承自 AttribDict,用于存储注入相关信息
 class InjectionDict(AttribDict):
     def __init__(self):
-        AttribDict.__init__(self)
-
-        self.place = None
-        self.parameter = None
-        self.ptype = None
-        self.prefix = None
-        self.suffix = None
-        self.clause = None
-        self.notes = []  # Note: https://github.com/sqlmapproject/sqlmap/issues/1888
-
-        # data is a dict with various stype, each which is a dict with
-        # all the information specific for that stype
+        AttribDict.__init__(self) # 调用 AttribDict 的初始化方法
+
+        # 初始化注入信息
+        self.place = None # 注入位置
+        self.parameter = None # 注入参数
+        self.ptype = None # 参数类型
+        self.prefix = None # 前缀
+        self.suffix = None # 后缀
+        self.clause = None # 子句
+        self.notes = []  # 备注列表
+
+        # data 字典存储不同类型的注入数据
         self.data = AttribDict()
 
-        # conf is a dict which stores current snapshot of important
-        # options used during detection
+        # conf 字典存储检测期间使用的重要选项的快照
         self.conf = AttribDict()
 
-        self.dbms = None
-        self.dbms_version = None
-        self.os = None
+        self.dbms = None # 数据库类型
+        self.dbms_version = None # 数据库版本
+        self.os = None # 操作系统
 
-# Reference: https://www.kunxi.org/2014/05/lru-cache-in-python
+# 定义 LRUDict 类,实现 LRU 缓存字典
+# 参考:https://www.kunxi.org/2014/05/lru-cache-in-python
 class LRUDict(object):
     """
     This class defines the LRU dictionary
@@ -141,40 +149,41 @@ class LRUDict(object):
     """
 
     def __init__(self, capacity):
-        self.capacity = capacity
-        self.cache = OrderedDict()
-        self.__lock = threading.Lock()
+        self.capacity = capacity # 设置缓存容量
+        self.cache = OrderedDict() # 使用 OrderedDict 作为缓存
+        self.__lock = threading.Lock() # 创建一个锁,用于线程同步
 
     def __len__(self):
-        return len(self.cache)
+        return len(self.cache) # 返回缓存长度
 
     def __contains__(self, key):
-        return key in self.cache
+        return key in self.cache # 判断键是否存在于缓存中
 
     def __getitem__(self, key):
-        value = self.cache.pop(key)
-        self.cache[key] = value
-        return value
+        value = self.cache.pop(key) # 将键从缓存中移除
+        self.cache[key] = value # 将键添加回缓存,移动到最后
+        return value # 返回键的值
 
     def get(self, key):
-        return self.__getitem__(key)
+        return self.__getitem__(key) # 获取键的值
 
     def __setitem__(self, key, value):
-        with self.__lock:
+        with self.__lock: # 获取锁,保证线程安全
             try:
-                self.cache.pop(key)
-            except KeyError:
-                if len(self.cache) >= self.capacity:
-                    self.cache.popitem(last=False)
-        self.cache[key] = value
+                self.cache.pop(key) # 尝试从缓存中删除键
+            except KeyError: # 如果键不存在
+                if len(self.cache) >= self.capacity: # 如果缓存已满
+                    self.cache.popitem(last=False) # 删除最老的项
+        self.cache[key] = value # 将键值添加到缓存中
 
     def set(self, key, value):
-        self.__setitem__(key, value)
+        self.__setitem__(key, value) # 设置键值
 
     def keys(self):
-        return self.cache.keys()
+        return self.cache.keys() # 返回缓存的所有键
 
-# Reference: https://code.activestate.com/recipes/576694/
+# 定义 OrderedSet 类,实现有序集合
+# 参考:https://code.activestate.com/recipes/576694/
 class OrderedSet(_collections.MutableSet):
     """
     This class defines the set with ordered (as added) items
@@ -192,57 +201,57 @@ class OrderedSet(_collections.MutableSet):
     """
 
     def __init__(self, iterable=None):
-        self.end = end = []
-        end += [None, end, end]         # sentinel node for doubly linked list
-        self.map = {}                   # key --> [key, prev, next]
+        self.end = end = [] # 创建哨兵节点
+        end += [None, end, end]         # 双向链表的哨兵节点
+        self.map = {}                   # 存储键值和链表节点的映射
         if iterable is not None:
-            self |= iterable
+            self |= iterable # 添加可迭代对象
 
     def __len__(self):
-        return len(self.map)
+        return len(self.map) # 返回集合长度
 
     def __contains__(self, key):
-        return key in self.map
+        return key in self.map # 判断键是否存在于集合中
 
     def add(self, value):
-        if value not in self.map:
+        if value not in self.map: # 如果值不在集合中
             end = self.end
             curr = end[1]
-            curr[2] = end[1] = self.map[value] = [value, curr, end]
+            curr[2] = end[1] = self.map[value] = [value, curr, end] # 添加新节点到链表尾部
 
     def discard(self, value):
-        if value in self.map:
-            value, prev, next = self.map.pop(value)
-            prev[2] = next
+        if value in self.map: # 如果值在集合中
+            value, prev, next = self.map.pop(value) # 移除节点
+            prev[2] = next # 更新链表
             next[1] = prev
 
     def __iter__(self):
         end = self.end
-        curr = end[2]
+        curr = end[2] # 从链表头开始遍历
         while curr is not end:
             yield curr[0]
-            curr = curr[2]
+            curr = curr[2] # 移动到下一个节点
 
     def __reversed__(self):
         end = self.end
-        curr = end[1]
+        curr = end[1] # 从链表尾开始遍历
         while curr is not end:
             yield curr[0]
-            curr = curr[1]
+            curr = curr[1] # 移动到上一个节点
 
     def pop(self, last=True):
-        if not self:
+        if not self: # 如果集合为空
             raise KeyError('set is empty')
-        key = self.end[1][0] if last else self.end[2][0]
-        self.discard(key)
-        return key
+        key = self.end[1][0] if last else self.end[2][0] # 获取最后一个或第一个元素
+        self.discard(key) # 移除元素
+        return key # 返回元素值
 
     def __repr__(self):
-        if not self:
+        if not self: # 如果集合为空
             return '%s()' % (self.__class__.__name__,)
-        return '%s(%r)' % (self.__class__.__name__, list(self))
+        return '%s(%r)' % (self.__class__.__name__, list(self)) # 返回字符串表示
 
     def __eq__(self, other):
-        if isinstance(other, OrderedSet):
-            return len(self) == len(other) and list(self) == list(other)
-        return set(self) == set(other)
+        if isinstance(other, OrderedSet): # 如果另一个对象是有序集合
+            return len(self) == len(other) and list(self) == list(other) # 比较长度和内容
+        return set(self) == set(other) # 比较集合内容
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/dbms/mssqlserver/fingerprint.py b/src/sqlmap-master/plugins/dbms/mssqlserver/fingerprint.py
index 1e8e492..9a6ba86 100644
--- a/src/sqlmap-master/plugins/dbms/mssqlserver/fingerprint.py
+++ b/src/sqlmap-master/plugins/dbms/mssqlserver/fingerprint.py
@@ -5,89 +5,96 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from lib.core.common import Backend
-from lib.core.common import Format
-from lib.core.convert import getUnicode
-from lib.core.data import conf
-from lib.core.data import kb
-from lib.core.data import logger
-from lib.core.enums import DBMS
-from lib.core.enums import OS
-from lib.core.session import setDbms
-from lib.core.settings import MSSQL_ALIASES
-from lib.request import inject
-from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
-
+# 导入必要的模块
+from lib.core.common import Backend # 导入 Backend 类,用于访问后端数据库信息
+from lib.core.common import Format # 导入 Format 类,用于格式化输出信息
+from lib.core.convert import getUnicode # 导入 getUnicode 函数,用于获取 Unicode 字符串
+from lib.core.data import conf # 导入 conf 对象,用于访问全局配置信息
+from lib.core.data import kb # 导入 kb 对象,用于访问全局知识库
+from lib.core.data import logger # 导入 logger 对象,用于输出日志
+from lib.core.enums import DBMS # 导入 DBMS 枚举,定义数据库管理系统类型
+from lib.core.enums import OS # 导入 OS 枚举,定义操作系统类型
+from lib.core.session import setDbms # 导入 setDbms 函数,用于设置数据库类型
+from lib.core.settings import MSSQL_ALIASES # 导入 MSSQL_ALIASES 常量,定义 SQL Server 的别名
+from lib.request import inject # 导入 inject 函数,用于执行 SQL 注入请求
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint # 导入 GenericFingerprint 类,作为当前类的父类
+
+# 定义 Fingerprint 类,继承自 GenericFingerprint
 class Fingerprint(GenericFingerprint):
+    # 初始化 Fingerprint 类,设置数据库类型为 MSSQL
     def __init__(self):
         GenericFingerprint.__init__(self, DBMS.MSSQL)
 
+    # 定义 getFingerprint 方法,用于获取数据库指纹信息
     def getFingerprint(self):
-        value = ""
-        wsOsFp = Format.getOs("web server", kb.headersFp)
+        value = "" # 初始化指纹信息字符串
+        wsOsFp = Format.getOs("web server", kb.headersFp) # 获取 Web 服务器操作系统信息
 
         if wsOsFp:
-            value += "%s\n" % wsOsFp
+            value += "%s\
+" % wsOsFp # 将 Web 服务器操作系统信息添加到指纹信息
 
-        if kb.data.banner:
-            dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
+        if kb.data.banner: # 如果存在数据库 banner 信息
+            dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) # 获取数据库操作系统信息
 
             if dbmsOsFp:
-                value += "%s\n" % dbmsOsFp
+                value += "%s\
+" % dbmsOsFp # 将数据库操作系统信息添加到指纹信息
 
-        value += "back-end DBMS: "
-        actVer = Format.getDbms()
+        value += "back-end DBMS: " # 添加数据库类型标签
+        actVer = Format.getDbms() # 获取数据库类型
 
-        if not conf.extensiveFp:
-            value += actVer
-            return value
+        if not conf.extensiveFp: # 如果不需要详细指纹信息
+            value += actVer # 将数据库类型添加到指纹信息
+            return value # 返回指纹信息
 
-        blank = " " * 15
-        value += "active fingerprint: %s" % actVer
+        blank = " " * 15 # 定义缩进空格
+        value += "active fingerprint: %s" % actVer # 添加当前指纹信息
 
-        if kb.bannerFp:
-            release = kb.bannerFp.get("dbmsRelease")
-            version = kb.bannerFp.get("dbmsVersion")
-            servicepack = kb.bannerFp.get("dbmsServicePack")
+        if kb.bannerFp: # 如果存在数据库 banner 信息
+            release = kb.bannerFp.get("dbmsRelease") # 获取数据库版本发布信息
+            version = kb.bannerFp.get("dbmsVersion") # 获取数据库版本信息
+            servicepack = kb.bannerFp.get("dbmsServicePack") # 获取数据库服务包信息
 
-            if release and version and servicepack:
-                banVer = "%s %s " % (DBMS.MSSQL, release)
-                banVer += "Service Pack %s " % servicepack
-                banVer += "version %s" % version
+            if release and version and servicepack: # 如果所有信息都存在
+                banVer = "%s %s " % (DBMS.MSSQL, release) # 构建 banner 版本信息
+                banVer += "Service Pack %s " % servicepack # 添加服务包信息
+                banVer += "version %s" % version # 添加版本信息
 
-                value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+                value += "\
+%sbanner parsing fingerprint: %s" % (blank, banVer) # 将 banner 版本信息添加到指纹信息
 
-        htmlErrorFp = Format.getErrorParsedDBMSes()
+        htmlErrorFp = Format.getErrorParsedDBMSes() # 获取 HTML 错误信息中的数据库信息
 
         if htmlErrorFp:
-            value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
+            value += "\
+%shtml error message fingerprint: %s" % (blank, htmlErrorFp) # 将 HTML 错误信息中的数据库信息添加到指纹信息
 
-        return value
+        return value # 返回指纹信息
 
+    # 定义 checkDbms 方法,用于检查数据库类型是否为 MSSQL
     def checkDbms(self):
-        if not conf.extensiveFp and Backend.isDbmsWithin(MSSQL_ALIASES):
-            setDbms("%s %s" % (DBMS.MSSQL, Backend.getVersion()))
-
-            self.getBanner()
-
-            Backend.setOs(OS.WINDOWS)
-
-            return True
+        if not conf.extensiveFp and Backend.isDbmsWithin(MSSQL_ALIASES): # 如果不需要详细指纹并且数据库别名匹配
+            setDbms("%s %s" % (DBMS.MSSQL, Backend.getVersion())) # 设置数据库类型
+            self.getBanner() # 获取数据库 banner 信息
+            Backend.setOs(OS.WINDOWS) # 设置操作系统类型为 Windows
+            return True # 返回 True
 
-        infoMsg = "testing %s" % DBMS.MSSQL
+        infoMsg = "testing %s" % DBMS.MSSQL # 输出正在测试 MSSQL 的信息
         logger.info(infoMsg)
 
         # NOTE: SELECT LEN(@@VERSION)=LEN(@@VERSION) FROM DUAL does not
         # work connecting directly to the Microsoft SQL Server database
-        if conf.direct:
-            result = True
+        if conf.direct: # 如果是直接连接
+            result = True # 直接设置为 True
         else:
-            result = inject.checkBooleanExpression("UNICODE(SQUARE(NULL)) IS NULL")
+            result = inject.checkBooleanExpression("UNICODE(SQUARE(NULL)) IS NULL") # 使用 SQL 注入检查
 
-        if result:
-            infoMsg = "confirming %s" % DBMS.MSSQL
+        if result: # 如果检查结果为 True
+            infoMsg = "confirming %s" % DBMS.MSSQL # 输出确认是 MSSQL 的信息
             logger.info(infoMsg)
 
+            # 遍历不同的 MSSQL 版本及其检查语句
             for version, check in (
                 ("2022", "CHARINDEX('16.0.',@@VERSION)>0"),
                 ("2019", "CHARINDEX('15.0.',@@VERSION)>0"),
@@ -100,48 +107,46 @@ class Fingerprint(GenericFingerprint):
                 ("2005", "XACT_STATE()=XACT_STATE()"),
                 ("2000", "HOST_NAME()=HOST_NAME()"),
             ):
-                result = inject.checkBooleanExpression(check)
+                result = inject.checkBooleanExpression(check) # 使用 SQL 注入检查版本
 
                 if result:
-                    Backend.setVersion(version)
+                    Backend.setVersion(version) # 设置数据库版本
                     break
 
             if Backend.getVersion():
-                setDbms("%s %s" % (DBMS.MSSQL, Backend.getVersion()))
+                setDbms("%s %s" % (DBMS.MSSQL, Backend.getVersion())) # 设置数据库类型和版本
             else:
-                setDbms(DBMS.MSSQL)
+                setDbms(DBMS.MSSQL) # 设置数据库类型
 
-            self.getBanner()
-
-            Backend.setOs(OS.WINDOWS)
-
-            return True
-        else:
-            warnMsg = "the back-end DBMS is not %s" % DBMS.MSSQL
+            self.getBanner() # 获取数据库 banner 信息
+            Backend.setOs(OS.WINDOWS) # 设置操作系统类型为 Windows
+            return True # 返回 True
+        else: # 如果检查结果为 False
+            warnMsg = "the back-end DBMS is not %s" % DBMS.MSSQL # 输出警告信息
             logger.warning(warnMsg)
+            return False # 返回 False
 
-            return False
-
+    # 定义 checkDbmsOs 方法,用于检查数据库操作系统信息
     def checkDbmsOs(self, detailed=False):
-        if Backend.getOs() and Backend.getOsVersion() and Backend.getOsServicePack():
+        if Backend.getOs() and Backend.getOsVersion() and Backend.getOsServicePack(): # 如果已获取操作系统信息,则直接返回
             return
 
-        if not Backend.getOs():
-            Backend.setOs(OS.WINDOWS)
+        if not Backend.getOs(): # 如果没有获取操作系统信息
+            Backend.setOs(OS.WINDOWS) # 设置操作系统类型为 Windows
 
-        if not detailed:
+        if not detailed: # 如果不需要详细信息,则直接返回
             return
 
-        infoMsg = "fingerprinting the back-end DBMS operating system "
+        infoMsg = "fingerprinting the back-end DBMS operating system " # 输出正在获取操作系统版本和服务包的信息
         infoMsg += "version and service pack"
         logger.info(infoMsg)
 
-        infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
+        infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs() # 输出操作系统类型
 
-        self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)")
-        inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION"))
+        self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)") # 创建支持表,用于存储版本信息
+        inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION")) # 将 @@VERSION 写入支持表
 
-        # Reference: https://en.wikipedia.org/wiki/Comparison_of_Microsoft_Windows_versions
+        # 参考:https://en.wikipedia.org/wiki/Comparison_of_Microsoft_Windows_versions
         # https://en.wikipedia.org/wiki/Windows_NT#Releases
         versions = {
             "NT": ("4.0", (6, 5, 4, 3, 2, 1)),
@@ -155,50 +160,50 @@ class Fingerprint(GenericFingerprint):
             "10 or 11 or 2016 or 2019 or 2022": ("10.0", (0,))
         }
 
-        # Get back-end DBMS underlying operating system version
+        # 获取数据库操作系统版本
         for version, data in versions.items():
-            query = "EXISTS(SELECT %s FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField)
-            query += "LIKE '%Windows NT " + data[0] + "%')"
-            result = inject.checkBooleanExpression(query)
+            query = "EXISTS(SELECT %s FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField) # 构建查询语句
+            query += "LIKE '%Windows NT " + data[0] + "%')" # 添加版本判断条件
+            result = inject.checkBooleanExpression(query) # 使用 SQL 注入检查
 
             if result:
-                Backend.setOsVersion(version)
-                infoMsg += " %s" % Backend.getOsVersion()
+                Backend.setOsVersion(version) # 设置操作系统版本
+                infoMsg += " %s" % Backend.getOsVersion() # 将操作系统版本信息添加到日志信息
                 break
 
-        if not Backend.getOsVersion():
-            Backend.setOsVersion("2003")
-            Backend.setOsServicePack(2)
+        if not Backend.getOsVersion(): # 如果没有获取到操作系统版本
+            Backend.setOsVersion("2003") # 默认设置为 2003
+            Backend.setOsServicePack(2) # 默认设置为服务包 2
 
             warnMsg = "unable to fingerprint the underlying operating "
             warnMsg += "system version, assuming it is Windows "
             warnMsg += "%s Service Pack %d" % (Backend.getOsVersion(), Backend.getOsServicePack())
             logger.warning(warnMsg)
 
-            self.cleanup(onlyFileTbl=True)
+            self.cleanup(onlyFileTbl=True) # 清理支持表
 
             return
 
-        # Get back-end DBMS underlying operating system service pack
-        sps = versions[Backend.getOsVersion()][1]
+        # 获取操作系统服务包
+        sps = versions[Backend.getOsVersion()][1] # 获取服务包列表
         for sp in sps:
-            query = "EXISTS(SELECT %s FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField)
-            query += "LIKE '%Service Pack " + getUnicode(sp) + "%')"
-            result = inject.checkBooleanExpression(query)
+            query = "EXISTS(SELECT %s FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField) # 构建查询语句
+            query += "LIKE '%Service Pack " + getUnicode(sp) + "%')" # 添加服务包判断条件
+            result = inject.checkBooleanExpression(query) # 使用 SQL 注入检查
 
             if result:
-                Backend.setOsServicePack(sp)
+                Backend.setOsServicePack(sp) # 设置操作系统服务包
                 break
 
-        if not Backend.getOsServicePack():
-            debugMsg = "assuming the operating system has no service pack"
+        if not Backend.getOsServicePack(): # 如果没有获取到服务包
+            debugMsg = "assuming the operating system has no service pack" # 输出调试信息
             logger.debug(debugMsg)
 
-            Backend.setOsServicePack(0)
+            Backend.setOsServicePack(0) # 默认设置为服务包 0
 
         if Backend.getOsVersion():
-            infoMsg += " Service Pack %d" % Backend.getOsServicePack()
+            infoMsg += " Service Pack %d" % Backend.getOsServicePack() # 将服务包信息添加到日志信息
 
         logger.info(infoMsg)
 
-        self.cleanup(onlyFileTbl=True)
+        self.cleanup(onlyFileTbl=True) # 清理支持表
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/dbms/vertica/fingerprint.py b/src/sqlmap-master/plugins/dbms/vertica/fingerprint.py
index d31ef61..fe5e574 100644
--- a/src/sqlmap-master/plugins/dbms/vertica/fingerprint.py
+++ b/src/sqlmap-master/plugins/dbms/vertica/fingerprint.py
@@ -5,102 +5,107 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from lib.core.common import Backend
-from lib.core.common import Format
-from lib.core.data import conf
-from lib.core.data import kb
-from lib.core.data import logger
-from lib.core.enums import DBMS
-from lib.core.session import setDbms
-from lib.core.settings import VERTICA_ALIASES
-from lib.request import inject
-from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
-
+# 导入必要的模块
+from lib.core.common import Backend # 导入 Backend 类,用于访问后端数据库信息
+from lib.core.common import Format # 导入 Format 类,用于格式化输出信息
+from lib.core.data import conf # 导入 conf 对象,用于访问全局配置信息
+from lib.core.data import kb # 导入 kb 对象,用于访问全局知识库
+from lib.core.data import logger # 导入 logger 对象,用于输出日志
+from lib.core.enums import DBMS # 导入 DBMS 枚举,定义数据库管理系统类型
+from lib.core.session import setDbms # 导入 setDbms 函数,用于设置数据库类型
+from lib.core.settings import VERTICA_ALIASES # 导入 VERTICA_ALIASES 常量,定义 Vertica 数据库的别名
+from lib.request import inject # 导入 inject 函数,用于执行 SQL 注入请求
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint # 导入 GenericFingerprint 类,作为当前类的父类
+
+# 定义 Fingerprint 类,继承自 GenericFingerprint
 class Fingerprint(GenericFingerprint):
+    # 初始化 Fingerprint 类,设置数据库类型为 Vertica
     def __init__(self):
         GenericFingerprint.__init__(self, DBMS.VERTICA)
 
+    # 定义 getFingerprint 方法,用于获取数据库指纹信息
     def getFingerprint(self):
-        value = ""
-        wsOsFp = Format.getOs("web server", kb.headersFp)
+        value = "" # 初始化指纹信息字符串
+        wsOsFp = Format.getOs("web server", kb.headersFp) # 获取 Web 服务器操作系统信息
 
         if wsOsFp:
-            value += "%s\n" % wsOsFp
+            value += "%s\
+" % wsOsFp # 将 Web 服务器操作系统信息添加到指纹信息
 
-        if kb.data.banner:
-            dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
+        if kb.data.banner: # 如果存在数据库 banner 信息
+            dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) # 获取数据库操作系统信息
 
             if dbmsOsFp:
-                value += "%s\n" % dbmsOsFp
+                value += "%s\
+" % dbmsOsFp # 将数据库操作系统信息添加到指纹信息
 
-        value += "back-end DBMS: "
+        value += "back-end DBMS: " # 添加数据库类型标签
 
-        if not conf.extensiveFp:
-            value += DBMS.VERTICA
-            return value
+        if not conf.extensiveFp: # 如果不需要详细指纹信息
+            value += DBMS.VERTICA # 将数据库类型添加到指纹信息
+            return value # 返回指纹信息
 
-        actVer = Format.getDbms()
-        blank = " " * 15
-        value += "active fingerprint: %s" % actVer
+        actVer = Format.getDbms() # 获取数据库类型
+        blank = " " * 15 # 定义缩进空格
+        value += "active fingerprint: %s" % actVer # 添加当前指纹信息
 
-        if kb.bannerFp:
-            banVer = kb.bannerFp.get("dbmsVersion")
+        if kb.bannerFp: # 如果存在数据库 banner 信息
+            banVer = kb.bannerFp.get("dbmsVersion") # 获取数据库版本信息
 
             if banVer:
-                banVer = Format.getDbms([banVer])
-                value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+                banVer = Format.getDbms([banVer]) # 格式化数据库版本信息
+                value += "\
+%sbanner parsing fingerprint: %s" % (blank, banVer) # 将 banner 版本信息添加到指纹信息
 
-        htmlErrorFp = Format.getErrorParsedDBMSes()
+        htmlErrorFp = Format.getErrorParsedDBMSes() # 获取 HTML 错误信息中的数据库信息
 
         if htmlErrorFp:
-            value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
+            value += "\
+%shtml error message fingerprint: %s" % (blank, htmlErrorFp) # 将 HTML 错误信息中的数据库信息添加到指纹信息
 
-        return value
+        return value # 返回指纹信息
 
+    # 定义 checkDbms 方法,用于检查数据库类型是否为 Vertica
     def checkDbms(self):
-        if not conf.extensiveFp and Backend.isDbmsWithin(VERTICA_ALIASES):
-            setDbms(DBMS.VERTICA)
-
-            self.getBanner()
-
-            return True
+        if not conf.extensiveFp and Backend.isDbmsWithin(VERTICA_ALIASES): # 如果不需要详细指纹并且数据库别名匹配
+            setDbms(DBMS.VERTICA) # 设置数据库类型为 Vertica
+            self.getBanner() # 获取数据库 banner 信息
+            return True # 返回 True
 
-        infoMsg = "testing %s" % DBMS.VERTICA
+        infoMsg = "testing %s" % DBMS.VERTICA # 输出正在测试 Vertica 的信息
         logger.info(infoMsg)
 
         # NOTE: Vertica works too without the CONVERT_TO()
-        result = inject.checkBooleanExpression("BITSTRING_TO_BINARY(NULL) IS NULL")
+        result = inject.checkBooleanExpression("BITSTRING_TO_BINARY(NULL) IS NULL") # 使用 SQL 注入检查
 
-        if result:
-            infoMsg = "confirming %s" % DBMS.VERTICA
+        if result: # 如果检查结果为 True
+            infoMsg = "confirming %s" % DBMS.VERTICA # 输出确认是 Vertica 的信息
             logger.info(infoMsg)
 
-            result = inject.checkBooleanExpression("HEX_TO_INTEGER(NULL) IS NULL")
+            result = inject.checkBooleanExpression("HEX_TO_INTEGER(NULL) IS NULL") # 使用 SQL 注入检查
 
-            if not result:
-                warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA
+            if not result: # 如果检查结果为 False
+                warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA # 输出警告信息
                 logger.warning(warnMsg)
+                return False # 返回 False
 
-                return False
+            setDbms(DBMS.VERTICA) # 设置数据库类型为 Vertica
+            self.getBanner() # 获取数据库 banner 信息
 
-            setDbms(DBMS.VERTICA)
+            if not conf.extensiveFp: # 如果不需要详细指纹信息
+                return True # 返回 True
 
-            self.getBanner()
-
-            if not conf.extensiveFp:
-                return True
-
-            infoMsg = "actively fingerprinting %s" % DBMS.VERTICA
+            infoMsg = "actively fingerprinting %s" % DBMS.VERTICA # 输出正在进行详细指纹识别的信息
             logger.info(infoMsg)
 
+            # 根据 CALENDAR_HIERARCHY_DAY(NULL) 的结果判断 Vertica 版本
             if inject.checkBooleanExpression("CALENDAR_HIERARCHY_DAY(NULL) IS NULL"):
-                Backend.setVersion(">= 9.0")
+                Backend.setVersion(">= 9.0") # 设置数据库版本为 >= 9.0
             else:
-                Backend.setVersion("< 9.0")
+                Backend.setVersion("< 9.0") # 设置数据库版本为 < 9.0
 
-            return True
-        else:
-            warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA
+            return True # 返回 True
+        else: # 如果检查结果为 False
+            warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA # 输出警告信息
             logger.warning(warnMsg)
-
-            return False
+            return False # 返回 False
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/generic/custom.py b/src/sqlmap-master/plugins/generic/custom.py
index dbfd589..fe5e574 100644
--- a/src/sqlmap-master/plugins/generic/custom.py
+++ b/src/sqlmap-master/plugins/generic/custom.py
@@ -5,146 +5,107 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-from __future__ import print_function
-
-import re
-import sys
-
-from lib.core.common import Backend
-from lib.core.common import dataToStdout
-from lib.core.common import getSQLSnippet
-from lib.core.common import isStackingAvailable
-from lib.core.convert import getUnicode
-from lib.core.data import conf
-from lib.core.data import logger
-from lib.core.dicts import SQL_STATEMENTS
-from lib.core.enums import AUTOCOMPLETE_TYPE
-from lib.core.enums import DBMS
-from lib.core.exception import SqlmapNoneDataException
-from lib.core.settings import METADB_SUFFIX
-from lib.core.settings import NULL
-from lib.core.settings import PARAMETER_SPLITTING_REGEX
-from lib.core.shell import autoCompletion
-from lib.request import inject
-from thirdparty.six.moves import input as _input
-
-class Custom(object):
-    """
-    This class defines custom enumeration functionalities for plugins.
-    """
-
+# 导入必要的模块
+from lib.core.common import Backend # 导入 Backend 类,用于访问后端数据库信息
+from lib.core.common import Format # 导入 Format 类,用于格式化输出信息
+from lib.core.data import conf # 导入 conf 对象,用于访问全局配置信息
+from lib.core.data import kb # 导入 kb 对象,用于访问全局知识库
+from lib.core.data import logger # 导入 logger 对象,用于输出日志
+from lib.core.enums import DBMS # 导入 DBMS 枚举,定义数据库管理系统类型
+from lib.core.session import setDbms # 导入 setDbms 函数,用于设置数据库类型
+from lib.core.settings import VERTICA_ALIASES # 导入 VERTICA_ALIASES 常量,定义 Vertica 数据库的别名
+from lib.request import inject # 导入 inject 函数,用于执行 SQL 注入请求
+from plugins.generic.fingerprint import Fingerprint as GenericFingerprint # 导入 GenericFingerprint 类,作为当前类的父类
+
+# 定义 Fingerprint 类,继承自 GenericFingerprint
+class Fingerprint(GenericFingerprint):
+    # 初始化 Fingerprint 类,设置数据库类型为 Vertica
     def __init__(self):
-        pass
-
-    def sqlQuery(self, query):
-        output = None
-        sqlType = None
-        query = query.rstrip(';')
+        GenericFingerprint.__init__(self, DBMS.VERTICA)
 
-        try:
-            for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
-                for sqlStatement in sqlStatements:
-                    if query.lower().startswith(sqlStatement):
-                        sqlType = sqlTitle
-                        break
+    # 定义 getFingerprint 方法,用于获取数据库指纹信息
+    def getFingerprint(self):
+        value = "" # 初始化指纹信息字符串
+        wsOsFp = Format.getOs("web server", kb.headersFp) # 获取 Web 服务器操作系统信息
 
-            if not re.search(r"\b(OPENROWSET|INTO)\b", query, re.I) and (not sqlType or "SELECT" in sqlType):
-                infoMsg = "fetching %s query output: '%s'" % (sqlType if sqlType is not None else "SQL", query)
-                logger.info(infoMsg)
+        if wsOsFp:
+            value += "%s\
+" % wsOsFp # 将 Web 服务器操作系统信息添加到指纹信息
 
-                if Backend.isDbms(DBMS.MSSQL):
-                    match = re.search(r"(\bFROM\s+)([^\s]+)", query, re.I)
-                    if match and match.group(2).count('.') == 1:
-                        query = query.replace(match.group(0), "%s%s" % (match.group(1), match.group(2).replace('.', ".dbo.")))
+        if kb.data.banner: # 如果存在数据库 banner 信息
+            dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp) # 获取数据库操作系统信息
 
-                query = re.sub(r"(?i)\w+%s\.?" % METADB_SUFFIX, "", query)
+            if dbmsOsFp:
+                value += "%s\
+" % dbmsOsFp # 将数据库操作系统信息添加到指纹信息
 
-                output = inject.getValue(query, fromUser=True)
+        value += "back-end DBMS: " # 添加数据库类型标签
 
-                return output
-            elif not isStackingAvailable() and not conf.direct:
-                warnMsg = "execution of non-query SQL statements is only "
-                warnMsg += "available when stacked queries are supported"
-                logger.warning(warnMsg)
+        if not conf.extensiveFp: # 如果不需要详细指纹信息
+            value += DBMS.VERTICA # 将数据库类型添加到指纹信息
+            return value # 返回指纹信息
 
-                return None
-            else:
-                if sqlType:
-                    infoMsg = "executing %s statement: '%s'" % (sqlType if sqlType is not None else "SQL", query)
-                else:
-                    infoMsg = "executing unknown SQL command: '%s'" % query
-                logger.info(infoMsg)
+        actVer = Format.getDbms() # 获取数据库类型
+        blank = " " * 15 # 定义缩进空格
+        value += "active fingerprint: %s" % actVer # 添加当前指纹信息
 
-                inject.goStacked(query)
+        if kb.bannerFp: # 如果存在数据库 banner 信息
+            banVer = kb.bannerFp.get("dbmsVersion") # 获取数据库版本信息
 
-                output = NULL
+            if banVer:
+                banVer = Format.getDbms([banVer]) # 格式化数据库版本信息
+                value += "\
+%sbanner parsing fingerprint: %s" % (blank, banVer) # 将 banner 版本信息添加到指纹信息
 
-        except SqlmapNoneDataException as ex:
-            logger.warning(ex)
-
-        return output
-
-    def sqlShell(self):
-        infoMsg = "calling %s shell. To quit type " % Backend.getIdentifiedDbms()
-        infoMsg += "'x' or 'q' and press ENTER"
-        logger.info(infoMsg)
+        htmlErrorFp = Format.getErrorParsedDBMSes() # 获取 HTML 错误信息中的数据库信息
 
-        autoCompletion(AUTOCOMPLETE_TYPE.SQL)
+        if htmlErrorFp:
+            value += "\
+%shtml error message fingerprint: %s" % (blank, htmlErrorFp) # 将 HTML 错误信息中的数据库信息添加到指纹信息
 
-        while True:
-            query = None
+        return value # 返回指纹信息
 
-            try:
-                query = _input("sql-shell> ")
-                query = getUnicode(query, encoding=sys.stdin.encoding)
-                query = query.strip("; ")
-            except UnicodeDecodeError:
-                print()
-                errMsg = "invalid user input"
-                logger.error(errMsg)
-            except KeyboardInterrupt:
-                print()
-                errMsg = "user aborted"
-                logger.error(errMsg)
-            except EOFError:
-                print()
-                errMsg = "exit"
-                logger.error(errMsg)
-                break
+    # 定义 checkDbms 方法,用于检查数据库类型是否为 Vertica
+    def checkDbms(self):
+        if not conf.extensiveFp and Backend.isDbmsWithin(VERTICA_ALIASES): # 如果不需要详细指纹并且数据库别名匹配
+            setDbms(DBMS.VERTICA) # 设置数据库类型为 Vertica
+            self.getBanner() # 获取数据库 banner 信息
+            return True # 返回 True
 
-            if not query:
-                continue
-
-            if query.lower() in ("x", "q", "exit", "quit"):
-                break
-
-            output = self.sqlQuery(query)
+        infoMsg = "testing %s" % DBMS.VERTICA # 输出正在测试 Vertica 的信息
+        logger.info(infoMsg)
 
-            if output and output != "Quit":
-                conf.dumper.sqlQuery(query, output)
+        # NOTE: Vertica works too without the CONVERT_TO()
+        result = inject.checkBooleanExpression("BITSTRING_TO_BINARY(NULL) IS NULL") # 使用 SQL 注入检查
 
-            elif not output:
-                pass
+        if result: # 如果检查结果为 True
+            infoMsg = "confirming %s" % DBMS.VERTICA # 输出确认是 Vertica 的信息
+            logger.info(infoMsg)
 
-            elif output != "Quit":
-                dataToStdout("No output\n")
+            result = inject.checkBooleanExpression("HEX_TO_INTEGER(NULL) IS NULL") # 使用 SQL 注入检查
 
-    def sqlFile(self):
-        infoMsg = "executing SQL statements from given file(s)"
-        logger.info(infoMsg)
+            if not result: # 如果检查结果为 False
+                warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA # 输出警告信息
+                logger.warning(warnMsg)
+                return False # 返回 False
 
-        for filename in re.split(PARAMETER_SPLITTING_REGEX, conf.sqlFile):
-            filename = filename.strip()
+            setDbms(DBMS.VERTICA) # 设置数据库类型为 Vertica
+            self.getBanner() # 获取数据库 banner 信息
 
-            if not filename:
-                continue
+            if not conf.extensiveFp: # 如果不需要详细指纹信息
+                return True # 返回 True
 
-            snippet = getSQLSnippet(Backend.getDbms(), filename)
+            infoMsg = "actively fingerprinting %s" % DBMS.VERTICA # 输出正在进行详细指纹识别的信息
+            logger.info(infoMsg)
 
-            if snippet and all(query.strip().upper().startswith("SELECT") for query in (_ for _ in snippet.split(';' if ';' in snippet else '\n') if _)):
-                for query in (_ for _ in snippet.split(';' if ';' in snippet else '\n') if _):
-                    query = query.strip()
-                    if query:
-                        conf.dumper.sqlQuery(query, self.sqlQuery(query))
+            # 根据 CALENDAR_HIERARCHY_DAY(NULL) 的结果判断 Vertica 版本
+            if inject.checkBooleanExpression("CALENDAR_HIERARCHY_DAY(NULL) IS NULL"):
+                Backend.setVersion(">= 9.0") # 设置数据库版本为 >= 9.0
             else:
-                conf.dumper.sqlQuery(snippet, self.sqlQuery(snippet))
+                Backend.setVersion("< 9.0") # 设置数据库版本为 < 9.0
+
+            return True # 返回 True
+        else: # 如果检查结果为 False
+            warnMsg = "the back-end DBMS is not %s" % DBMS.VERTICA # 输出警告信息
+            logger.warning(warnMsg)
+            return False # 返回 False
\ No newline at end of file
diff --git a/src/sqlmap-master/plugins/generic/misc.py b/src/sqlmap-master/plugins/generic/misc.py
index 7eb710b..ccc5c44 100644
--- a/src/sqlmap-master/plugins/generic/misc.py
+++ b/src/sqlmap-master/plugins/generic/misc.py
@@ -5,200 +5,211 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
 See the file 'LICENSE' for copying permission
 """
 
-import ntpath
-import re
-
-from lib.core.common import Backend
-from lib.core.common import hashDBWrite
-from lib.core.common import isStackingAvailable
-from lib.core.common import normalizePath
-from lib.core.common import ntToPosixSlashes
-from lib.core.common import posixToNtSlashes
-from lib.core.common import readInput
-from lib.core.common import singleTimeDebugMessage
-from lib.core.common import unArrayizeValue
-from lib.core.data import conf
-from lib.core.data import kb
-from lib.core.data import logger
-from lib.core.data import queries
-from lib.core.enums import DBMS
-from lib.core.enums import HASHDB_KEYS
-from lib.core.enums import OS
-from lib.core.exception import SqlmapNoneDataException
-from lib.request import inject
-
+# 导入必要的模块
+import ntpath # 导入 ntpath 模块,用于处理 Windows 路径
+import re # 导入 re 模块,用于正则表达式
+
+from lib.core.common import Backend # 导入 Backend 类,用于访问后端数据库信息
+from lib.core.common import hashDBWrite # 导入 hashDBWrite 函数,用于写入哈希数据库
+from lib.core.common import isStackingAvailable # 导入 isStackingAvailable 函数,用于检查是否支持堆叠查询
+from lib.core.common import normalizePath # 导入 normalizePath 函数,用于规范化路径
+from lib.core.common import ntToPosixSlashes # 导入 ntToPosixSlashes 函数,用于将 Windows 路径转换为 POSIX 路径
+from lib.core.common import posixToNtSlashes # 导入 posixToNtSlashes 函数,用于将 POSIX 路径转换为 Windows 路径
+from lib.core.common import readInput # 导入 readInput 函数,用于读取用户输入
+from lib.core.common import singleTimeDebugMessage # 导入 singleTimeDebugMessage 函数,用于输出单次调试信息
+from lib.core.common import unArrayizeValue # 导入 unArrayizeValue 函数,用于将数组值转换为单个值
+from lib.core.data import conf # 导入 conf 对象,用于访问全局配置信息
+from lib.core.data import kb # 导入 kb 对象,用于访问全局知识库
+from lib.core.data import logger # 导入 logger 对象,用于输出日志
+from lib.core.data import queries # 导入 queries 字典,存储数据库查询语句
+from lib.core.enums import DBMS # 导入 DBMS 枚举,定义数据库管理系统类型
+from lib.core.enums import HASHDB_KEYS # 导入 HASHDB_KEYS 枚举,定义哈希数据库键值
+from lib.core.enums import OS # 导入 OS 枚举,定义操作系统类型
+from lib.core.exception import SqlmapNoneDataException # 导入 SqlmapNoneDataException 异常类
+from lib.request import inject # 导入 inject 函数,用于执行 SQL 注入请求
+
+# 定义 Miscellaneous 类,用于实现杂项功能
 class Miscellaneous(object):
     """
     This class defines miscellaneous functionalities for plugins.
     """
 
+    # 初始化 Miscellaneous 类
     def __init__(self):
         pass
 
+    # 定义 getRemoteTempPath 方法,用于获取远程临时路径
     def getRemoteTempPath(self):
-        if not conf.tmpPath and Backend.isDbms(DBMS.MSSQL):
-            debugMsg = "identifying Microsoft SQL Server error log directory "
+        if not conf.tmpPath and Backend.isDbms(DBMS.MSSQL): # 如果没有设置临时路径且数据库是 MSSQL
+            debugMsg = "identifying Microsoft SQL Server error log directory " # 输出调试信息
             debugMsg += "that sqlmap will use to store temporary files with "
             debugMsg += "commands' output"
             logger.debug(debugMsg)
 
-            _ = unArrayizeValue(inject.getValue("SELECT SERVERPROPERTY('ErrorLogFileName')", safeCharEncode=False))
+            _ = unArrayizeValue(inject.getValue("SELECT SERVERPROPERTY('ErrorLogFileName')", safeCharEncode=False)) # 获取错误日志文件路径
 
-            if _:
-                conf.tmpPath = ntpath.dirname(_)
+            if _: # 如果获取到路径
+                conf.tmpPath = ntpath.dirname(_) # 设置临时路径为错误日志文件所在的目录
 
-        if not conf.tmpPath:
-            if Backend.isOs(OS.WINDOWS):
-                if conf.direct:
-                    conf.tmpPath = "%TEMP%"
+        if not conf.tmpPath: # 如果没有设置临时路径
+            if Backend.isOs(OS.WINDOWS): # 如果操作系统是 Windows
+                if conf.direct: # 如果是直接连接
+                    conf.tmpPath = "%TEMP%" # 设置临时路径为 %TEMP%
                 else:
-                    self.checkDbmsOs(detailed=True)
+                    self.checkDbmsOs(detailed=True) # 检测数据库操作系统
 
-                    if Backend.getOsVersion() in ("2000", "NT"):
-                        conf.tmpPath = "C:/WINNT/Temp"
-                    elif Backend.isOs("XP"):
-                        conf.tmpPath = "C:/Documents and Settings/All Users/Application Data/Temp"
-                    else:
-                        conf.tmpPath = "C:/Windows/Temp"
-            else:
-                conf.tmpPath = "/tmp"
+                    if Backend.getOsVersion() in ("2000", "NT"): # 如果是 Windows 2000 或 NT
+                        conf.tmpPath = "C:/WINNT/Temp" # 设置临时路径
+                    elif Backend.isOs("XP"): # 如果是 Windows XP
+                        conf.tmpPath = "C:/Documents and Settings/All Users/Application Data/Temp" # 设置临时路径
+                    else: # 如果是其他 Windows 版本
+                        conf.tmpPath = "C:/Windows/Temp" # 设置临时路径
+            else: # 如果操作系统不是 Windows
+                conf.tmpPath = "/tmp" # 设置临时路径为 /tmp
 
-        if re.search(r"\A[\w]:[\/\\]+", conf.tmpPath, re.I):
-            Backend.setOs(OS.WINDOWS)
+        if re.search(r"\A[\w]:[\/\$$+", conf.tmpPath, re.I): # 如果临时路径是 Windows 格式
+            Backend.setOs(OS.WINDOWS) # 设置操作系统为 Windows
 
-        conf.tmpPath = normalizePath(conf.tmpPath)
-        conf.tmpPath = ntToPosixSlashes(conf.tmpPath)
+        conf.tmpPath = normalizePath(conf.tmpPath) # 规范化临时路径
+        conf.tmpPath = ntToPosixSlashes(conf.tmpPath) # 将临时路径转换为 POSIX 格式
 
-        singleTimeDebugMessage("going to use '%s' as temporary files directory" % conf.tmpPath)
+        singleTimeDebugMessage("going to use '%s' as temporary files directory" % conf.tmpPath) # 输出调试信息
 
-        hashDBWrite(HASHDB_KEYS.CONF_TMP_PATH, conf.tmpPath)
+        hashDBWrite(HASHDB_KEYS.CONF_TMP_PATH, conf.tmpPath) # 写入哈希数据库
 
-        return conf.tmpPath
+        return conf.tmpPath # 返回临时路径
 
+    # 定义 getVersionFromBanner 方法,用于从 banner 中获取数据库版本
     def getVersionFromBanner(self):
-        if "dbmsVersion" in kb.bannerFp:
-            return
+        if "dbmsVersion" in kb.bannerFp: # 如果 banner 中已经有版本信息
+            return # 直接返回
 
-        infoMsg = "detecting back-end DBMS version from its banner"
+        infoMsg = "detecting back-end DBMS version from its banner" # 输出信息
         logger.info(infoMsg)
 
-        query = queries[Backend.getIdentifiedDbms()].banner.query
+        query = queries[Backend.getIdentifiedDbms()].banner.query # 获取 banner 查询语句
 
-        if conf.direct:
-            query = "SELECT %s" % query
+        if conf.direct: # 如果是直接连接
+            query = "SELECT %s" % query # 添加 SELECT 关键字
 
-        kb.bannerFp["dbmsVersion"] = unArrayizeValue(inject.getValue(query)) or ""
+        kb.bannerFp["dbmsVersion"] = unArrayizeValue(inject.getValue(query)) or "" # 获取 banner 信息
 
-        match = re.search(r"\d[\d.-]*", kb.bannerFp["dbmsVersion"])
-        if match:
-            kb.bannerFp["dbmsVersion"] = match.group(0)
+        match = re.search(r"\d[\d.-]*", kb.bannerFp["dbmsVersion"]) # 使用正则表达式匹配版本号
+        if match: # 如果匹配成功
+            kb.bannerFp["dbmsVersion"] = match.group(0) # 设置版本号
 
+    # 定义 delRemoteFile 方法,用于删除远程文件
     def delRemoteFile(self, filename):
-        if not filename:
-            return
+        if not filename: # 如果文件名为空
+            return # 直接返回
 
-        self.checkDbmsOs()
+        self.checkDbmsOs() # 检测数据库操作系统
 
-        if Backend.isOs(OS.WINDOWS):
-            filename = posixToNtSlashes(filename)
-            cmd = "del /F /Q %s" % filename
-        else:
-            cmd = "rm -f %s" % filename
+        if Backend.isOs(OS.WINDOWS): # 如果操作系统是 Windows
+            filename = posixToNtSlashes(filename) # 将路径转换为 Windows 格式
+            cmd = "del /F /Q %s" % filename # 构建删除命令
+        else: # 如果操作系统不是 Windows
+            cmd = "rm -f %s" % filename # 构建删除命令
 
-        self.execCmd(cmd, silent=True)
+        self.execCmd(cmd, silent=True) # 执行删除命令
 
+    # 定义 createSupportTbl 方法,用于创建支持表
     def createSupportTbl(self, tblName, tblField, tblType):
-        inject.goStacked("DROP TABLE %s" % tblName, silent=True)
+        inject.goStacked("DROP TABLE %s" % tblName, silent=True) # 删除表(如果存在)
 
-        if Backend.isDbms(DBMS.MSSQL) and tblName == self.cmdTblName:
-            inject.goStacked("CREATE TABLE %s(id INT PRIMARY KEY IDENTITY, %s %s)" % (tblName, tblField, tblType))
-        else:
-            inject.goStacked("CREATE TABLE %s(%s %s)" % (tblName, tblField, tblType))
+        if Backend.isDbms(DBMS.MSSQL) and tblName == self.cmdTblName: # 如果是 MSSQL 并且表名是命令表
+            inject.goStacked("CREATE TABLE %s(id INT PRIMARY KEY IDENTITY, %s %s)" % (tblName, tblField, tblType)) # 创建表,包含自增 id
+        else: # 如果不是 MSSQL 或表名不是命令表
+            inject.goStacked("CREATE TABLE %s(%s %s)" % (tblName, tblField, tblType)) # 创建表
 
+    # 定义 cleanup 方法,用于清理文件系统和数据库
     def cleanup(self, onlyFileTbl=False, udfDict=None, web=False):
         """
         Cleanup file system and database from sqlmap create files, tables
         and functions
         """
 
-        if web and self.webBackdoorFilePath:
-            logger.info("cleaning up the web files uploaded")
+        if web and self.webBackdoorFilePath: # 如果是 web 模式且有 web 后门文件路径
+            logger.info("cleaning up the web files uploaded") # 输出信息
 
-            self.delRemoteFile(self.webStagerFilePath)
-            self.delRemoteFile(self.webBackdoorFilePath)
+            self.delRemoteFile(self.webStagerFilePath) # 删除 web stager 文件
+            self.delRemoteFile(self.webBackdoorFilePath) # 删除 web 后门文件
 
-        if (not isStackingAvailable() or kb.udfFail) and not conf.direct:
-            return
+        if (not isStackingAvailable() or kb.udfFail) and not conf.direct: # 如果不支持堆叠查询或 udf失败且不是直接连接
+            return # 直接返回
 
-        if any((conf.osCmd, conf.osShell)) and Backend.isDbms(DBMS.PGSQL) and kb.copyExecTest:
-            return
+        if any((conf.osCmd, conf.osShell)) and Backend.isDbms(DBMS.PGSQL) and kb.copyExecTest: # 如果执行系统命令/shell 且是 PostgreSQL 且 copyExecTest 为 True
+            return # 直接返回
 
-        if Backend.isOs(OS.WINDOWS):
-            libtype = "dynamic-link library"
+        if Backend.isOs(OS.WINDOWS): # 如果操作系统是 Windows
+            libtype = "dynamic-link library" # 设置库类型为动态链接库
 
-        elif Backend.isOs(OS.LINUX):
-            libtype = "shared object"
+        elif Backend.isOs(OS.LINUX): # 如果操作系统是 Linux
+            libtype = "shared object" # 设置库类型为共享对象
 
-        else:
-            libtype = "shared library"
+        else: # 如果是其他操作系统
+            libtype = "shared library" # 设置库类型为共享库
 
-        if onlyFileTbl:
-            logger.debug("cleaning up the database management system")
-        else:
-            logger.info("cleaning up the database management system")
+        if onlyFileTbl: # 如果只清理文件表
+            logger.debug("cleaning up the database management system") # 输出调试信息
+        else: # 如果清理所有
+            logger.info("cleaning up the database management system") # 输出信息
 
-        logger.debug("removing support tables")
-        inject.goStacked("DROP TABLE %s" % self.fileTblName, silent=True)
-        inject.goStacked("DROP TABLE %shex" % self.fileTblName, silent=True)
+        logger.debug("removing support tables") # 输出调试信息
+        inject.goStacked("DROP TABLE %s" % self.fileTblName, silent=True) # 删除文件表
+        inject.goStacked("DROP TABLE %shex" % self.fileTblName, silent=True) # 删除文件表 (hex)
 
-        if not onlyFileTbl:
-            inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True)
+        if not onlyFileTbl: # 如果不是只清理文件表
+            inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True) # 删除命令表
 
-            if Backend.isDbms(DBMS.MSSQL):
-                udfDict = {"master..new_xp_cmdshell": {}}
+            if Backend.isDbms(DBMS.MSSQL): # 如果是 MSSQL
+                udfDict = {"master..new_xp_cmdshell": {}} # 设置要删除的 udf (xp_cmdshell)
 
-            if udfDict is None:
-                udfDict = getattr(self, "sysUdfs", {})
+            if udfDict is None: # 如果 udfDict 为空
+                udfDict = getattr(self, "sysUdfs", {}) # 获取系统 udf
 
-            for udf, inpRet in udfDict.items():
-                message = "do you want to remove UDF '%s'? [Y/n] " % udf
+            for udf, inpRet in udfDict.items(): # 遍历 udf
+                message = "do you want to remove UDF '%s'? [Y/n] " % udf # 输出询问信息
 
-                if readInput(message, default='Y', boolean=True):
-                    dropStr = "DROP FUNCTION %s" % udf
+                if readInput(message, default='Y', boolean=True): # 获取用户输入
+                    dropStr = "DROP FUNCTION %s" % udf # 构建删除 udf 命令
 
-                    if Backend.isDbms(DBMS.PGSQL):
-                        inp = ", ".join(i for i in inpRet["input"])
-                        dropStr += "(%s)" % inp
+                    if Backend.isDbms(DBMS.PGSQL): # 如果是 PostgreSQL
+                        inp = ", ".join(i for i in inpRet["input"]) # 获取输入参数
+                        dropStr += "(%s)" % inp # 添加输入参数到删除命令
 
-                    logger.debug("removing UDF '%s'" % udf)
-                    inject.goStacked(dropStr, silent=True)
+                    logger.debug("removing UDF '%s'" % udf) # 输出调试信息
+                    inject.goStacked(dropStr, silent=True) # 删除 udf
 
-            logger.info("database management system cleanup finished")
+            logger.info("database management system cleanup finished") # 输出信息
 
-            warnMsg = "remember that UDF %s files " % libtype
+            warnMsg = "remember that UDF %s files " % libtype # 构建警告信息
 
-            if conf.osPwn:
-                warnMsg += "and Metasploit related files in the temporary "
+            if conf.osPwn: # 如果开启 osPwn 功能
+                warnMsg += "and Metasploit related files in the temporary " # 添加 Metasploit 相关文件信息
                 warnMsg += "folder "
 
-            warnMsg += "saved on the file system can only be deleted "
+            warnMsg += "saved on the file system can only be deleted " # 添加手动删除信息
             warnMsg += "manually"
-            logger.warning(warnMsg)
+            logger.warning(warnMsg) # 输出警告信息
 
+    # 定义 likeOrExact 方法,用于选择 LIKE 或精确匹配
     def likeOrExact(self, what):
-        message = "do you want sqlmap to consider provided %s(s):\n" % what
-        message += "[1] as LIKE %s names (default)\n" % what
+        message = "do you want sqlmap to consider provided %s(s):\
+" % what # 构建询问信息
+        message += "[1] as LIKE %s names (default)\
+" % what
         message += "[2] as exact %s names" % what
 
-        choice = readInput(message, default='1')
+        choice = readInput(message, default='1') # 获取用户选择
 
-        if not choice or choice == '1':
+        if not choice or choice == '1': # 如果选择 LIKE 匹配
             choice = '1'
-            condParam = " LIKE '%%%s%%'"
-        elif choice == '2':
-            condParam = "='%s'"
-        else:
-            errMsg = "invalid value"
-            raise SqlmapNoneDataException(errMsg)
-
-        return choice, condParam
+            condParam = " LIKE '%%%s%%'" # 设置 LIKE 条件
+        elif choice == '2': # 如果选择精确匹配
+            condParam = "='%s'" # 设置精确匹配条件
+        else: # 如果输入非法
+            errMsg = "invalid value" # 输出错误信息
+            raise SqlmapNoneDataException(errMsg) # 抛出异常
+
+        return choice, condParam # 返回选择和条件
\ No newline at end of file
-- 
2.34.1