当前位置: 首页>>代码示例>>Python>>正文


Python Config.get_options方法代码示例

本文整理汇总了Python中lib.core.config.Config.get_options方法的典型用法代码示例。如果您正苦于以下问题:Python Config.get_options方法的具体用法?Python Config.get_options怎么用?Python Config.get_options使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在lib.core.config.Config的用法示例。


在下文中一共展示了Config.get_options方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: __init__

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
class Analyzer:
    """Cuckoo Windows Analyzer.

    This class handles the initialization and execution of the analysis
    procedure, including handling of the pipe server, the auxiliary modules and
    the analysis packages.
    """
    PIPE_SERVER_COUNT = 4

    def __init__(self):
        self.pipes = [None]*self.PIPE_SERVER_COUNT
        self.config = None
        self.target = None

    def pids_from_process_name_list(self, namelist):
        proclist = []
        pidlist = []
        buf = create_string_buffer(1024 * 1024)
        p = cast(buf, c_void_p)
        retlen = c_ulong(0)
        retval = NTDLL.NtQuerySystemInformation(5, buf, 1024 * 1024, byref(retlen))
        if retval:
           return []
        proc = cast(p, POINTER(SYSTEM_PROCESS_INFORMATION)).contents
        while proc.NextEntryOffset:
            p.value += proc.NextEntryOffset
            proc = cast(p, POINTER(SYSTEM_PROCESS_INFORMATION)).contents
            proclist.append((proc.ImageName.Buffer[:proc.ImageName.Length/2], proc.UniqueProcessId))

        for proc in proclist:
            lowerproc = proc[0].lower()
            for name in namelist:
                if lowerproc == name:
                    pidlist.append(proc[1])
                    break
        return pidlist

    def prepare(self):
        """Prepare env for analysis."""
        global DEFAULT_DLL
        global SERVICES_PID
        global HIDE_PIDS

        # Get SeDebugPrivilege for the Python process. It will be needed in
        # order to perform the injections.
        grant_debug_privilege()

        # randomize cuckoomon DLL and loader executable names
        copy("dll\\cuckoomon.dll", CUCKOOMON32_NAME)
        copy("dll\\cuckoomon_x64.dll", CUCKOOMON64_NAME)
        copy("bin\\loader.exe", LOADER32_NAME)
        copy("bin\\loader_x64.exe", LOADER64_NAME)

        # Create the folders used for storing the results.
        create_folders()

        add_protected_path(os.getcwd())
        add_protected_path(PATHS["root"])

        # Initialize logging.
        init_logging()

        # Parse the analysis configuration file generated by the agent.
        self.config = Config(cfg="analysis.conf")

        # Set virtual machine clock.
        clock = datetime.strptime(self.config.clock, "%Y%m%dT%H:%M:%S")
        # Setting date and time.
        # NOTE: Windows system has only localized commands with date format
        # following localization settings, so these commands for english date
        # format cannot work in other localizations.
        # In addition DATE and TIME commands are blocking if an incorrect
        # syntax is provided, so an echo trick is used to bypass the input
        # request and not block analysis.
        thedate = clock.strftime("%m-%d-%y")
        thetime = clock.strftime("%H:%M:%S")
        os.system("echo:|date {0}".format(thedate))
        os.system("echo:|time {0}".format(thetime))
        log.info("Date set to: {0}, time set to: {1}".format(thedate, thetime))

        # Set the default DLL to be used by the PipeHandler.
        DEFAULT_DLL = self.config.get_options().get("dll")

        # get PID for services.exe for monitoring services
        svcpid = self.pids_from_process_name_list(["services.exe"])
        if svcpid:
            SERVICES_PID = svcpid[0]

        protected_procname_list = [
            "vmwareuser.exe",
            "vmwareservice.exe",
            "vboxservice.exe",
            "vboxtray.exe",
            "sandboxiedcomlaunch.exe",
            "sandboxierpcss.exe",
            "procmon.exe",
            "regmon.exe",
            "filemon.exe",
            "wireshark.exe",
            "netmon.exe",
#.........这里部分代码省略.........
开发者ID:marek2003,项目名称:cuckoo-modified,代码行数:103,代码来源:analyzer.py

示例2: inject

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
    def inject(self, dll=None, interest=None, nosleepskip=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param interest: path to file of interest, handed to cuckoomon config
        @param apc: APC use.
        """
        if not self.pid:
            log.warning("No valid pid specified, injection aborted")
            return False

        thread_id = 0
        if self.thread_id:
            thread_id = self.thread_id

        if not self.is_alive():
            log.warning("The process with pid %s is not alive, "
                        "injection aborted", self.pid)
            return False

        is_64bit = self.is_64bit()
        if not dll:
            if is_64bit:
                dll = "cuckoomon_x64.dll"
            else:
                dll = "cuckoomon.dll"

        dll = randomize_bin(os.path.join("dll", dll), "dll")

        if not dll or not os.path.exists(dll):
            log.warning("No valid DLL specified to be injected in process "
                        "with pid %d, injection aborted.", self.pid)
            return False

        config_path = "C:\\%s.ini" % self.pid
        with open(config_path, "w") as config:
            cfg = Config("analysis.conf")
            cfgoptions = cfg.get_options()

            # start the logserver for this monitored process
            self.logserver = LogServer(cfg.ip, cfg.port, self.logserver_path)

            firstproc = Process.first_process

            config.write("host-ip={0}\n".format(cfg.ip))
            config.write("host-port={0}\n".format(cfg.port))
            config.write("pipe={0}\n".format(PIPE))
            config.write("logserver={0}\n".format(self.logserver_path))
            config.write("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format("1" if firstproc else "0"))
            config.write("startup-time={0}\n".format(Process.startup_time))
            config.write("file-of-interest={0}\n".format(interest))
            config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX))
            config.write("terminate-event={0}{1}\n".format(TERMINATE_EVENT, self.pid))
            if nosleepskip:
                config.write("force-sleepskip=0\n")
            elif "force-sleepskip" in cfgoptions:
                config.write("force-sleepskip={0}\n".format(cfgoptions["force-sleepskip"]))
            if "full-logs" in cfgoptions:
                config.write("full-logs={0}\n".format(cfgoptions["full-logs"]))
            if "no-stealth" in cfgoptions:
                config.write("no-stealth={0}\n".format(cfgoptions["no-stealth"]))
            if "norefer" not in cfgoptions:
                config.write("referrer={0}\n".format(get_referrer_url(interest)))
            if firstproc:
                Process.first_process = False

        if thread_id or self.suspended:
            log.debug("Using QueueUserAPC injection.")
        else:
            log.debug("Using CreateRemoteThread injection.")

        orig_bin_name = ""
        bit_str = ""
        if is_64bit:
            orig_bin_name = "loader_x64.exe"
            bit_str = "64-bit"
        else:
            orig_bin_name = "loader.exe"
            bit_str = "32-bit"

        bin_name = randomize_bin(os.path.join("bin", orig_bin_name), "exe")

        if os.path.exists(bin_name):
            ret = subprocess.call([bin_name, "inject", str(self.pid), str(thread_id), dll])
            if ret != 0:
                if ret == 1:
                    log.info("Injected into suspended %s process with pid %d", bit_str, self.pid)
                else:
                    log.error("Unable to inject into %s process with pid %d, error: %d", bit_str, self.pid, ret)
                return False
            else:
                return True
        else:
            log.error("Please place the %s binary from cuckoomon into analyzer/windows/bin in order to analyze %s binaries.", os.path.basename(bin_name), bit_str)
            return False
开发者ID:feliperalmeida,项目名称:cuckoo-modified,代码行数:98,代码来源:process.py

示例3: inject

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
    def inject(self, dll=None, apc=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param apc: APC use.
        """
        if not self.pid:
            log.warning("No valid pid specified, injection aborted")
            return False

        if not self.is_alive():
            log.warning("The process with pid %s is not alive, " "injection aborted", self.pid)
            return False

        if not dll:
            dll = "cuckoomon.dll"

        dll = randomize_dll(os.path.join("dll", dll))

        if not dll or not os.path.exists(dll):
            log.warning("No valid DLL specified to be injected in process " "with pid %d, injection aborted.", self.pid)
            return False

        arg = KERNEL32.VirtualAllocEx(self.h_process, None, len(dll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)

        if not arg:
            log.error(
                "VirtualAllocEx failed when injecting process with " "pid %d, injection aborted (Error: %s)",
                self.pid,
                get_error_string(KERNEL32.GetLastError()),
            )
            return False

        bytes_written = c_int(0)
        if not KERNEL32.WriteProcessMemory(self.h_process, arg, dll + "\x00", len(dll) + 1, byref(bytes_written)):
            log.error(
                "WriteProcessMemory failed when injecting process with " "pid %d, injection aborted (Error: %s)",
                self.pid,
                get_error_string(KERNEL32.GetLastError()),
            )
            return False

        kernel32_handle = KERNEL32.GetModuleHandleA("kernel32.dll")
        load_library = KERNEL32.GetProcAddress(kernel32_handle, "LoadLibraryA")

        config_path = os.path.join(os.getenv("TEMP"), "%s.ini" % self.pid)
        with open(config_path, "w") as config:
            cfg = Config("analysis.conf")
            cfgoptions = cfg.get_options()

            # The first time we come up with a random startup-time.
            if Process.first_process:
                # This adds 1 up to 30 times of 20 minutes to the startup
                # time of the process, therefore bypassing anti-vm checks
                # which check whether the VM has only been up for <10 minutes.
                Process.startup_time = random.randint(1, 30) * 20 * 60 * 1000

            config.write("host-ip={0}\n".format(cfg.ip))
            config.write("host-port={0}\n".format(cfg.port))
            config.write("pipe={0}\n".format(PIPE))
            config.write("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format("1" if Process.first_process else "0"))
            config.write("startup-time={0}\n".format(Process.startup_time))
            config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX))
            config.write("force-sleepskip={0}\n".format(cfgoptions.get("force-sleepskip", "0")))

            Process.first_process = False

        if apc or self.suspended:
            log.debug("Using QueueUserAPC injection.")
            if not self.h_thread:
                log.info(
                    "No valid thread handle specified for injecting " "process with pid %d, injection aborted.",
                    self.pid,
                )
                return False

            if not KERNEL32.QueueUserAPC(load_library, self.h_thread, arg):
                log.error(
                    "QueueUserAPC failed when injecting process with " "pid %d (Error: %s)",
                    self.pid,
                    get_error_string(KERNEL32.GetLastError()),
                )
                return False
        else:
            event_name = "CuckooEvent%d" % self.pid
            self.event_handle = KERNEL32.CreateEventA(None, False, False, event_name)
            if not self.event_handle:
                log.warning("Unable to create notify event..")
                return False

            log.debug("Using CreateRemoteThread injection.")
            new_thread_id = c_ulong(0)
            thread_handle = KERNEL32.CreateRemoteThread(
                self.h_process, None, 0, load_library, arg, 0, byref(new_thread_id)
            )
            if not thread_handle:
                log.error(
                    "CreateRemoteThread failed when injecting process " "with pid %d (Error: %s)",
                    self.pid,
#.........这里部分代码省略.........
开发者ID:scottydo,项目名称:cuckoo,代码行数:103,代码来源:process.py

示例4: __init__

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
class Analyzer:
    """Cuckoo Windows Analyzer.

    This class handles the initialization and execution of the analysis
    procedure, including handling of the pipe server, the auxiliary modules and
    the analysis packages.
    """
    PIPE_SERVER_COUNT = 4

    def __init__(self):
        self.pipes = [None]*self.PIPE_SERVER_COUNT
        self.config = None
        self.target = None

    def prepare(self):
        """Prepare env for analysis."""
        global DEFAULT_DLL
        global SERVICES_PID

        # Get SeDebugPrivilege for the Python process. It will be needed in
        # order to perform the injections.
        grant_debug_privilege()

        # Create the folders used for storing the results.
        create_folders()

        add_protected_path(os.getcwd())
        add_protected_path(PATHS["root"])

        # Initialize logging.
        init_logging()

        # Parse the analysis configuration file generated by the agent.
        self.config = Config(cfg="analysis.conf")

        # Set virtual machine clock.
        clock = datetime.strptime(self.config.clock, "%Y%m%dT%H:%M:%S")
        # Setting date and time.
        # NOTE: Windows system has only localized commands with date format
        # following localization settings, so these commands for english date
        # format cannot work in other localizations.
        # In addition DATE and TIME commands are blocking if an incorrect
        # syntax is provided, so an echo trick is used to bypass the input
        # request and not block analysis.
        os.system("echo:|date {0}".format(clock.strftime("%m-%d-%y")))
        os.system("echo:|time {0}".format(clock.strftime("%H:%M:%S")))

        # Set the default DLL to be used by the PipeHandler.
        DEFAULT_DLL = self.config.get_options().get("dll")

        # get PID for services.exe for monitoring services
        # tasklist sometimes fails under high-load (http://support.microsoft.com/kb/2732840)
        # We can retry a few times to hopefully work around failures
        retries = 4
        while retries > 0: 
            stdin, stdout, stderr = os.popen3("tasklist /V /FI \"IMAGENAME eq services.exe\"")
            s = stdout.read()
            err = stderr.read()
            if 'services.exe' not in s:
                log.warning('tasklist failed with error "%s"' % (err))
            else:
                # it worked
                break
            retries -= 1


        if 'services.exe' not in s:
            # All attempts failed
            log.error('Unable to retreive services.exe PID')
            SERVICES_PID = None
        else:
            servidx = s.index("services.exe")
            servstr = s[servidx + 12:].strip()
            SERVICES_PID = int(servstr[:servstr.index(' ')], 10)
            log.debug('services.exe PID is %s' % (SERVICES_PID))

        # Initialize and start the Pipe Servers. This is going to be used for
        # communicating with the injected and monitored processes.
        for x in xrange(self.PIPE_SERVER_COUNT):
            self.pipes[x] = PipeServer()
            self.pipes[x].daemon = True
            self.pipes[x].start()

        # We update the target according to its category. If it's a file, then
        # we store the path.
        if self.config.category == "file":
            self.target = os.path.join(os.environ["TEMP"] + os.sep,
                                       str(self.config.file_name))
        # If it's a URL, well.. we store the URL.
        else:
            self.target = self.config.target

    def complete(self):
        """End analysis."""
        # Stop the Pipe Servers.
        for x in xrange(self.PIPE_SERVER_COUNT):
            self.pipes[x].stop()

        # Dump all the notified files.
        dump_files()
#.........这里部分代码省略.........
开发者ID:spark2k06,项目名称:cuckoo-modified,代码行数:103,代码来源:analyzer.py

示例5: __init__

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
class Analyzer:
    """Cuckoo Linux Analyzer.

    This class handles the initialization and execution of the analysis
    procedure, including the auxiliary modules and the analysis packages.
    """

    def __init__(self):
        self.config = None
        self.target = None

    def prepare(self):
        """Prepare env for analysis."""

        # Create the folders used for storing the results.
        create_folders()

        # Initialize logging.
        init_logging()

        # Parse the analysis configuration file generated by the agent.
        self.config = Config(cfg="analysis.conf")

        if self.config.get("clock", None):
            # Set virtual machine clock.
            clock = datetime.datetime.strptime(self.config.clock, "%Y%m%dT%H:%M:%S")
            # Setting date and time.
            os.system("date -s \"{0}\"".format(clock.strftime("%y-%m-%d %H:%M:%S")))

        # We update the target according to its category. If it's a file, then
        # we store the path.
        if self.config.category == "file":
            self.target = os.path.join(tempfile.gettempdir(), self.config.file_name)
        # If it's a URL, well.. we store the URL.
        else:
            self.target = self.config.target

    def complete(self):
        """End analysis."""
        # Dump all the notified files.
        dump_files()

        # Hell yeah.
        log.info("Analysis completed.")

    def run(self):
        """Run analysis.
        @return: operation status.
        """
        self.prepare()

        log.debug("Starting analyzer from: %s", os.getcwd())
        log.debug("Storing results at: %s", PATHS["root"])

        # If no analysis package was specified at submission, we try to select
        # one automatically.
        if not self.config.package:
            log.debug("No analysis package specified, trying to detect "
                      "it automagically.")

            if self.config.category == "file":
                package = "generic"
            else:
                package = "wget"

            # If we weren't able to automatically determine the proper package,
            # we need to abort the analysis.
            if not package:
                raise CuckooError("No valid package available for file "
                                  "type: {0}".format(self.config.file_type))

            log.info("Automatically selected analysis package \"%s\"", package)
        # Otherwise just select the specified package.
        else:
            package = self.config.package

        # Generate the package path.
        package_name = "modules.packages.%s" % package

        # Try to import the analysis package.
        try:
            __import__(package_name, globals(), locals(), ["dummy"], -1)
        # If it fails, we need to abort the analysis.
        except ImportError:
            raise CuckooError("Unable to import package \"{0}\", does "
                              "not exist.".format(package_name))

        # Initialize the package parent abstract.
        Package()

        # Enumerate the abstract subclasses.
        try:
            package_class = Package.__subclasses__()[0]
        except IndexError as e:
            raise CuckooError("Unable to select package class "
                              "(package={0}): {1}".format(package_name, e))

        # Initialize the analysis package.
        pack = package_class(self.config.get_options())

#.........这里部分代码省略.........
开发者ID:CERT-Polska,项目名称:cuckoo,代码行数:103,代码来源:analyzer.py

示例6: inject

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]
    def inject(self, dll=None, interest=None, nosleepskip=False):
        """Cuckoo DLL injection.
        @param dll: Cuckoo DLL path.
        @param interest: path to file of interest, handed to cuckoomon config
        @param apc: APC use.
        """
        global LOGSERVER_POOL

        if not self.pid:
            return False

        thread_id = 0
        if self.thread_id:
            thread_id = self.thread_id

        if not self.is_alive():
            log.warning("The process with pid %s is not alive, "
                        "injection aborted", self.pid)
            return False

        is_64bit = self.is_64bit()
        if not dll:
            if is_64bit:
                dll = CUCKOOMON64_NAME
            else:
                dll = CUCKOOMON32_NAME
        else:
            os.path.join("dll", dll)

        dll = os.path.join(os.getcwd(), dll)

        if not dll or not os.path.exists(dll):
            log.warning("No valid DLL specified to be injected in process "
                        "with pid %d, injection aborted.", self.pid)
            return False

        if thread_id or self.suspended:
            log.debug("Using QueueUserAPC injection.")
        else:
            log.debug("Using CreateRemoteThread injection.")

        config_path = "C:\\%s.ini" % self.pid
        with open(config_path, "w") as config:
            cfg = Config("analysis.conf")
            cfgoptions = cfg.get_options()

            # start the logserver for this monitored process
            logserver_path = LOGSERVER_PREFIX + str(self.pid)
            if logserver_path not in LOGSERVER_POOL:
                LOGSERVER_POOL[logserver_path] = LogServer(cfg.ip, cfg.port, logserver_path)

            Process.process_num += 1
            firstproc = Process.process_num == 1

            config.write("host-ip={0}\n".format(cfg.ip))
            config.write("host-port={0}\n".format(cfg.port))
            config.write("pipe={0}\n".format(PIPE))
            config.write("logserver={0}\n".format(logserver_path))
            config.write("results={0}\n".format(PATHS["root"]))
            config.write("analyzer={0}\n".format(os.getcwd()))
            config.write("first-process={0}\n".format("1" if firstproc else "0"))
            config.write("startup-time={0}\n".format(Process.startup_time))
            config.write("file-of-interest={0}\n".format(interest))
            config.write("shutdown-mutex={0}\n".format(SHUTDOWN_MUTEX))
            config.write("terminate-event={0}{1}\n".format(TERMINATE_EVENT, self.pid))

            if nosleepskip or ("force-sleepskip" not in cfgoptions and len(interest) > 2 and interest[1] != ':' and interest[0] != '\\' and Process.process_num <= 2):
                config.write("force-sleepskip=0\n")

            if "norefer" not in cfgoptions and "referrer" not in cfgoptions:
                config.write("referrer={0}\n".format(get_referrer_url(interest)))

            simple_optnames = [
                "force-sleepskip",
                "full-logs",
                "force-flush",
                "no-stealth",
                "buffer-max",
                "large-buffer-max",
                "serial",
                "sysvol_ctimelow",
                "sysvol_ctimehigh",
                "sys32_ctimelow",
                "sys32_ctimehigh",
                "debug",
                "disable_hook_content",
                "hook-type",
                "exclude-apis",
                "exclude-dlls",
                "referrer",
                ]
            
            for optname in simple_optnames:
                if optname in cfgoptions:
                    config.write("{0}={1}\n".format(optname, cfgoptions[optname]))

        orig_bin_name = ""
        bit_str = ""
        if is_64bit:
            orig_bin_name = LOADER64_NAME
#.........这里部分代码省略.........
开发者ID:Magicked,项目名称:cuckoo-modified,代码行数:103,代码来源:process.py

示例7: prepare

# 需要导入模块: from lib.core.config import Config [as 别名]
# 或者: from lib.core.config.Config import get_options [as 别名]

#.........这里部分代码省略.........
                raise CuckooError("No valid package available for file "
                                  "type: {0}".format(self.config.file_type))

            log.info("Automatically selected analysis package \"%s\"", package)
        # Otherwise just select the specified package.
        else:
            package = self.config.package

        return package

    def initialize_package(self, package):
        # Generate the package path.
        package_name = "modules.packages.%s" % package

        # Try to import the analysis package.
        try:
            __import__(package_name, globals(), locals(), ["dummy"], -1)
        # If it fails, we need to abort the analysis.
        except ImportError:
            raise CuckooError("Unable to import package \"{0}\", does "
                              "not exist.".format(package_name))

        # Initialize the package parent abstract.
        Package()

        # Enumerate the abstract subclasses.
        try:
            package_class = Package.__subclasses__()[0]
        except IndexError as e:
            raise CuckooError("Unable to select package class "
                              "(package={0}): {1}".format(package_name, e))

        # Initialize the analysis package.
        pack = package_class(self.config.get_options())

    def setup_auxiliary_modules(self):
        # Initialize Auxiliary modules
        Auxiliary()
        prefix = auxiliary.__name__ + "."
        for loader, name, ispkg in pkgutil.iter_modules(
                auxiliary.__path__, prefix):
            if ispkg:
                continue

            # Import the auxiliary module.
            try:
                __import__(name, globals(), locals(), ["dummy"], -1)
            except ImportError as e:
                log.warning("Unable to import the auxiliary module "
                            "\"%s\": %s", name, e)

        # Walk through the available auxiliary modules.
        aux_enabled, aux_avail = [], []
        for module in Auxiliary.__subclasses__():
            # Try to start the auxiliary module.
            try:
                aux = module(self.config.get_options())
                aux_avail.append(aux)
                aux.start()
            except (NotImplementedError, AttributeError):
                log.warning("Auxiliary module %s was not implemented",
                            aux.__class__.__name__)
                continue
            except Exception as e:
                log.warning("Cannot execute auxiliary module %s: %s",
                            aux.__class__.__name__, e)
开发者ID:phretor,项目名称:cuckoo-osx-analyzer,代码行数:70,代码来源:analyzer.py


注:本文中的lib.core.config.Config.get_options方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。