Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何加速PowerShell端口扫描程序_Multithreading_Powershell_Sockets - Fatal编程技术网

Multithreading 如何加速PowerShell端口扫描程序

Multithreading 如何加速PowerShell端口扫描程序,multithreading,powershell,sockets,Multithreading,Powershell,Sockets,出于各种原因,我开始编写PowerShell portscanner,不仅仅是为了开始学习它 使用的第一次迭代测试网络连接。这似乎太慢了;所以我降低了一个级别来使用套接字,特别是System.Net.sockets.TcpClient。(我们已经开始研究System.Net.Sockets.Socket,因为MS文档提到了Socket.BeginConnect(),它可以启动远程连接的异步请求,但不确定这是否有帮助。) 这看起来还是太慢了,所以我看了看乔布斯。所有这些都是为了不增加太多的速度而消

出于各种原因,我开始编写PowerShell portscanner,不仅仅是为了开始学习它

使用的第一次迭代
测试网络连接
。这似乎太慢了;所以我降低了一个级别来使用套接字,特别是
System.Net.sockets.TcpClient
。(我们已经开始研究
System.Net.Sockets.Socket
,因为MS文档提到了
Socket.BeginConnect()
,它可以启动远程连接的异步请求,但不确定这是否有帮助。)

这看起来还是太慢了,所以我看了看乔布斯。所有这些都是为了不增加太多的速度而消耗更多的资源,所以在谷歌搜索了很多次之后,我设法通过使用
RunSpacePools
使线程(或者PowerShell称之为线程)工作。我认为这已经基本完成了,如果您查看的是一个包含5个IP地址的输入文件,那么性能还可以。然而,今天早上用CIDR/24进行了试验,大约需要20-30分钟

[Edit]我应该补充一点,该脚本将采用“线程”值,但如果没有提供,则使用默认线程值
核心数+1
,以利用RunSpacePool多线程

因此,我开始研究Fyodor是如何提高速度的,在他所在州的
扫描艺术中(同时谈到TCP Connect()扫描):

同时对中的每个目标端口进行单独的connect()调用 线性时尚比慢速连接要花很多时间,你可以加快速度 通过并行使用多个套接字进行扫描

这显然是可以进行一些优化的地方

那么,有没有人能为我指明如何实现这一点的方向?正如我所说,对PoSH来说还是很陌生的,所以我用
RunSpacePools
来突破我理解的极限。 具体地说,我想要一些建议:a)如果我的直觉正确,可以提高扫描速度以提高套接字并行性;b)如何做到这一点;c)如果
System.Net.Sockets.socket
更合适

function doConnect {
    $ipLoopCount = 0
    $portLoopCount = 0
    # check for randomise switch
    if ($randomise) {
        $ipArray = makeRange | Sort-Object {Get-Random}
        $portArray = makePortRange | Sort-Object {Get-Random}
    } else {
        # Connects to IPs in order
        $ipArray = makeRange
        $portArray = makePortRange
    }
    # initialise runspaces
    if ($threads) {
        $useThreads = $threads
    } else {
        $useThreads = ([int]$env:NUMBER_OF_PROCESSORS + 1)
    }
    $pool = [RunspaceFactory]::CreateRunspacePool(1, $useThreads)
    $pool.ApartmentState = "MTA"
    $pool.Open()
    $runspaces = @()
    # set higher priority for powershell process
    if ($priority) {
        $proc = Get-Process -Id $pid;
        $proc.PriorityClass = 'High'
    } else{
        $proc = Get-Process -Id $pid;
        $proc.PriorityClass = 'Normal'
    }

    # info object
    $infoDisplay = @{
        InputFile = $inFile
        Target_IPs = $ipArray
        Target_Ports = $portArray
        Process_Priority = $proc.PriorityClass
        Threads = $useThreads
    }
    [PSCustomObject]$infoDisplay
    # set up scriptblock to pass to runspaces
    $scriptblock = {
        Param (
            [IPAddress]$sb_ip,
            [int]$sb_port
        )
        # This progress bar doesn't work yet
        Write-Progress -Activity "Scan range $StartIPaddress - $EndIPAddress" -Status "% Complete:" -PercentComplete((($portLoopCount)/($ipArray.Length*$portArray.Length))*100)
        if ($delay) {
            $delay = Get-Random -Maximum 1000 -Minimum 1;
            Start-Sleep -m $delay
        }
        $socket = New-Object System.Net.Sockets.TcpClient
        $socket.Connect($sb_ip, $sb_Port)
        if ($socket.Connected) {
            Write-Output "Connected to $sb_port on $sb_ip"
        #} else {
        #    Write-Output "Failed to connect to port $sb_port on $sb_ip"
        }
        $socket.Close()
    }

    foreach ($nIP in $ipArray) {
        $ipLoopCount++
        foreach ($nPort in $portArray) {
            $portLoopCount++
            $runspace = [PowerShell]::Create()
            $null = $runspace.AddScript($scriptblock)
            $null = $runspace.AddArgument($nIP)
            $null = $runspace.AddArgument($nPort)
            $runspace.RunspacePool = $pool
            $runspaces += [PSCustomObject]@{
                Pipe = $runspace;
                Status = $runspace.BeginInvoke()
            }
        }
    }
    while ($runspaces.Status -ne $null) {
        $completed = $runspaces | Where-Object { $_.Status.IsCompleted -eq $true }
        foreach ($runspace in $completed) {
            $runspace.Pipe.EndInvoke($runspace.Status)
            $runspace.Status = $null
        }
    } 

    $pool.Close()
    $pool.Dispose()
}
在PowerShell中尝试这一点可能是完全错误的,但这是一个有用的练习,因为环境已完全锁定,并且不可能安装“适当”的端口扫描程序(即nmap)

[Edit 2]我不认为减少超时并将其导入逻辑是我所追求的解决方案

[Edit 3]并联开关没有帮助


[Edit 4]一直在考虑异步套接字连接,因为这可能有助于提高总体连接速度,但随后必须有另一个线程/进程来处理传入的通信量。不确定疗效。

您能否详细说明您需要帮助的具体内容?“我有点卡住了”并不是很具体:)这是一个公正的评论。完成!您是否尝试过在工作流中实现foreach-parallel?不知道它能给你多大的速度,但值得一试<代码>只能在工作流中使用“-parallel”参数
。我必须理解这个概念,而不是以前遇到的。这似乎是相当基本的知识:/workflow往往是可靠的,但速度很慢,因此切换到workflow可能不是最好的选择。