花式反沙箱

news2024/11/18 8:49:59

编者注:本文仅供学习研究,严禁从事非法活动,任何后果由使用者本人负责。

前言

目前沙箱正成为判断恶意威胁的一种最快速和最简单的方式,因此反沙箱检测在实战中发挥越来越重要的作用,无论是从反溯源还是延长加载器寿命的角度,反沙箱都是红蓝对抗中不可或缺的一环。

我会着重讲解我觉得有趣的手法,当然有趣不等于实用,如果你分析过APT组织的样本,会发现那些原理简单且有效的方法会被更多的使用(比如主机名/用户名/进程黑名单,环境检测,用户交互检测等),这些方法往往都是复合使用的,因为很难有一种方法可以适用所有场景。出于学习的目的我们应该都了解一下。

我将反沙箱的手法笼统的分为了几类:时间规避类、环境检测类、硬件检测类、信息搜集类、用户交互类、其它类。篇幅原因,在这一篇主要介绍前两类。

许多资料由于时间太久,忘记从哪里学到(白嫖)的了,参考文献如有遗漏请各位师傅提醒,文章中有哪里不对也欢迎大佬指正。

一、时间规避类

本来我想将这类命名为延迟执行类,但是有些手法不属于延时执行但也与时间检测有关,实在不好划分,所以我将其整合为一个类别,都是基于时间的规避技术。

1)最基础的反沙箱——延时执行

出于性能的考虑,沙箱不可能一直等待一个进程执行,所以有一些聪明的攻击者想到如果在执行恶意代码之前先停一段时间,只要停的时间够长,是不是就绕过了沙箱的检测呢?事实证明在沙箱环境开始识别并防御这种攻击之前,这是可行的。攻击者利用已知的一些Windows API(比如我们都知道的sleep)来延迟执行恶意代码。

其它类似的API还有WaitForSingleObject,WaitForSingleObjectEx,NtWaitForSingleObject,SetTimer, SetWaitableTimer,CreateTimerQueueTimer等等。

这里举一个比较有趣的例子,就是利用Windows socket的select函数延时。

select的作用就是确定套接口的状态,对于每一个socket,调用者可以查询它的可读性、可写性及错误状态信息。结构如下:

图片

我们可以看到它一共有五个参数,唯一一个与时间有关的就是最后一个参数,timeout他是一个指向timeval的指针,表示等待的最长时间。

图片

timeval是一个结构体,用于指定时间间隔。

我们只需要建立一个socket连接,然后调用这个api去查询socket状态就可以了,这个调用消耗的时间就是我们上面提到的timeval里设置的时间。主要代码如下(前面建立socket的代码省略了):

    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(sock, &Write);
    FD_SET(sock, &Err);
    timeval tv = { 0 };
    tv.tv_usec = timeout * 1000;

    // check if the socket is ready, this call should take Timeout milliseconds
    select(0, NULL, &Write, &Err, &tv);

可惜这种方式在风靡一段时间后,很快被沙箱加速针对性的和谐掉了。

2)getTickCount

虽然沙箱厂商通过加速代码执行的方式解决了延时执行带来的影响,但是反沙箱的本质不就是区分沙箱和实体机的区别吗?沙箱加速恰恰成为了新的特征。攻击者开始通过多种方法来识别环境中的加速执行机制。有多款恶意软件家族(包括Win32/Kovter)会在代码中使用GetTickCount这个Windows API来判断代码运行时间是否匹配预期时间,我们也在一些恶意软件家族中看到该方法的一些改进版。GetTickCount返回(retrieve)从操作系统启动所经过(elapsed)的毫秒数:

图片

这种方式很聪明的利用了加速执行带来的差异识别出来沙箱环境,但同样很容易被绕过,只需要Hook这些计算时间间隔的api就可以很好的解决这个问题。也有一些文章建议创建超过20分钟的快照,让主机运行更长时间。但我觉得这种解决方案的开销太大了。

所谓智者千虑,必有一失。一个沙箱Hook了GetTickCount,但是还有GetLocalTime,Hook了GetLocalTime,还会有GetSystemTime。或许想绕过所有沙箱可能很有难度,但是针对一个特定的沙箱想找到一个未被Hook的计时方法还是很简单的。

我当初学到这里也有一些疑问:

1.假如找到的方法只针对特定的沙箱,如何才能同时绕过多个沙箱呢?——写一个使用多个API的并行时间检测。

2.如果真的找不到合适的计算时间间隔的API呢?——从外部服务获取时间,比如NTP。

3.如果从外部源获取时间的API也被HOOK了呢?——可以自己搭建一个服务专门仅用于返回时间。

攻防就像千层饼一样,你觉得不行的方法,深入一层没准又可以了。

3)API Flooding

单纯的拖延时间似乎太明显了,沙箱可以很轻松的识别检测出你调用了哪些API用来延时。如果能将延时和正常业务结合在一起,那检测难度无疑会变得更高。API Flooding(API泛洪)就是通过循环调用无用API来延迟恶意代码的执行。使用该方法的恶意软件代码片段如下:

图片

GetSystemTimeAdjustment的作用是确定系统是否对其时钟应用定期时间调整,并获取任何此类调整的值和周期。通过循环调用这个API达到延时的效果。

如果想知道这个方法更有效的实战,可以看下本文参考文献里的al-khaser项目。

4)内联代码

由于沙箱不能有效的处理某些API Flooding的逻辑,所以这种方法很可能会造成Dos效果。而且正如上文所说,沙箱是可以检测程序调用的API的,因此处理这种基于API的延时也不是什么难事。所以攻击者们引入另一种方式:内联汇编。

图片

原理很简单,在循环1里执行一些无效操作,比如上述代码里的mov edx,edx,循环了指定次数后再跳入循环2继续执行。至于要执行多少循环取决于你想让这段代码延时多久。

幸运的是截止我上次测试(大约五个月前),这种方法仍能绕过许多高级沙箱。不幸的是,许多杀软很干脆的把这段延时汇编直接识别为恶意代码。

5)CPUID

上述的几种方法都是基于延时执行或者由其引出的一些特性来进行沙箱检测的。由于虚拟化自身的特性,也会造成某些指令的执行在虚拟环境和真实环境中有时间差异。

得益于Hypervisor的普及,许多作弊软件制作者利用虚拟化技术逃避了反作弊引擎的检测。与此对应,反作弊引擎的厂商也没有坐以待毙,研究出了一系列检测虚拟化的方法。接下来要介绍的就是来自BattlEye的反沙箱方法。

原理:

首先我们要知道CPUID是什么,它为什么能够作为检测沙箱的指标:CPUID 在真实硬件上是一条相对快捷的指令,通常只需要 200 个周期,而在虚拟化环境中,由于内省引擎产生的开销,它可能需要十倍甚至更多的时间。

    unsigned __int64 old_priority = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); 
    unsigned __int64 rdtsc_first = __rdtsc();
    Sleep(2000);
    unsigned __int64 rdtsc_time_delta = __rdtsc() - rdtsc_first;
    DWORD64 result_time = 0;
    int cpuid_data[4] = { 0 };
    for (std::size_t count = 0; count < 0x6694; count++)
    {
        auto rdtsc_iter_time = __rdtsc();

        __cpuid((int*)cpuid_data, 0);

        result_time += __rdtsc() - rdtsc_iter_time;
    }
    unsigned __int64 _time = 10000000 * result_time / rdtsc_time_delta / 0x65;
    if (_time > 400 || _time < 10)
        exit(0);

    SetThreadPriority(GetCurrentThread(), old_priority);

上面这段代码就是这种方法的关键部分,通过计时器计算cpuid执行的平均CPU周期,假如与真实环境的CPU周期差距过大则判断为沙箱,退出程序。

正如一开始说的,CPUID在虚拟化环境中,占用的CPU周期会大幅上升。本质原因就在于这类指令会触发vmexit,在调用一些虚拟机无法完成指令的时候,就会触发它退出虚拟化,然后再执行指令。假如可以绕过vmexit也就绕过了这种检测方式。

不得不说逆向出battleye反沙箱代码的国外大佬不仅技术厉害,在产品方面更有独到的见解。虽然没有直接给出改进的代码,但是给出了反反沙箱的方法和更新建议。

检测方法和缺陷:

1.时间伪造:每次执行CPUID时减少TSC。VMCS 中的 TSC 偏移。

TSC即时间戳计数器,每次执行CPUID时减少TSC很好理解,很直接的篡改计数器。

VMCS中 TSC偏移量 表示该VMCS所代表的虚拟CPU TSC相对于物理CPU TSC的偏移, 即虚拟TSC=物理TSC+TSC偏移量. 当客户软件执行RDTSC时, 处理器直接返回虚拟TSC, 不产生VM-Exit. 这样, 对TSC的虚拟化只需在 适时更新VMCS中TSC偏移量即可, 不需要每次TSC访问都产生VM-Exit。(也就是我上文提到的绕过vmexit)

2.CPUID这个指令的执行时间在处理器之间差异很大,70-300个周期都有可能。

3.SetThreadPriority,正如代码里所写,我们使用这个函数增加了线程的优先级,但是这个方法容易受到中断或者其它进程的干扰,并不能保证这个线程可以被直接调用。

有检测方法,那肯定也有反检测方法(反反反沙箱?)。

改进方法:

1)禁用中断,将CR8修改为最高等级IRQL。

CR8是任务优先级寄存器,存储的就是当前IRQL等级。IRQL即中断请求级别,在同一处理器上,线程只能被更高级别IRQL的线程能中断,每个处理器都有自己的中断IRQL。

2)使用其它计时器替代TSC。

比如ACPI计时器、HPET、PIT、GPU计时器等。这里推荐APERF计时器,因为它难以伪造,并且仅在逻辑处理器处于 C0状态时才累计计数。

但有还有一个问题,那就是CPUID的执行时间在处理器之间差异很大,所以引出了下一种方法。

6)基于FYL2XP1的CPUID执行时间检测

说白了,就是以FYL2XP1这条命令的执行时间作为参照物来分析CPUID。

对于FYL2XP1这条命令其实不需要了解太多,我们只需要知道两点:

1.FYL2XP1是一条算术运算指令,平均执行时间正常情况下比CPUID长。

2.这条指令可以可靠的计时。

所以当CPUID指令的执行时间比FYL2XP1指令的平均执行时间长,就可以确定该系统是虚拟化的。

bool take_time()
{

    constexpr auto measure_time = 5;

    long long __cpuid_time   = 0;
    long long __fyl2xp1_time = 0;

    LARGE_INTEGER frequency = {};
    LARGE_INTEGER start     = {};
    LARGE_INTEGER end       = {};

    QueryPerformanceFrequency(&frequency);

    // count the average time it takes to execute a CPUID instruction
    for (std::size_t i = 0; i < measure_time; ++i)
    {
        QueryPerformanceCounter(&start);
        _cpuid_buffer_t cpuid_data;
        __cpuid(reinterpret_cast<int*>(&cpuid_data), 1);
        QueryPerformanceCounter(&end);

        auto delta = end.QuadPart - start.QuadPart;

        delta *= 1000000000;
        delta /= frequency.QuadPart;

        __cpuid_time += delta;
    }

    // count the average time it takes to execute a FYL2XP1 instruction
    for (std::size_t i = 0; i < measure_time; ++i)
    {
        QueryPerformanceCounter(&start);
        #ifdef _WIN64
        _asm_fyl2xp1();
        #else
        _asm FYL2XP1
        #endif
        QueryPerformanceCounter(&end);

        auto delta = end.QuadPart - start.QuadPart;

        delta *= 1000000000;
        delta /= frequency.QuadPart;

        __fyl2xp1_time += delta;
    }

    return __fyl2xp1_time <= __cpuid_time;
}

bool take_time_cpuid_against_fyl2xp1()
{
    constexpr auto measure_times = 5;
    auto positives               = 0;
    auto negatives               = 0;

    // run the internal VM check multiple times to get an average result
    for (auto i = measure_times; i != 0; --i)
        take_time() ? ++positives : ++negatives;

    // if there are more positive results than negative results, the
    // process is likely running inside a VM
    const bool decision = (positives >= negatives);

    return decision;
}

这段代码截取自github项目Hypervisor-Detection,经过了多组循环测试。take_time循环计算了fy12xp1和cpuid的周期大小并返回平均CPU周期的对比结果。take_time_cpuid_against_fyl2xp1为了确保准确,进行了多组测试。

当然CPUID不止如此,在反沙箱领域中还有其它妙用,后面的篇章我会陆续讲到。

7)特定时间执行

可以将我们的程序设置为每个小时的55分执行,或者设置为每个周的某一天执行。虽然有一定局限性,但想检测到我只能靠运气!

8)设置有效时间

最基础的也是加一个时间检测,超过指定时间之后就不再执行恶意代码。进阶一点的可以考虑将shellcode存放在oss的存储桶中远程拉取,但是设置链接的有效时间为2小时。

等蓝队拿到样本的时候我们已经销声匿迹了。

小结

关于时间规避沙箱检测的部分已经讲完了,但是还有许多方法我没有涉及到。就像我上面虽然说延时执行现在已经被沙箱加速很轻松的绕过,但是仍有一些大佬以此为基础创造出了更好的利用方法,例如利用计划任务,不仅可以延迟执行,也可以逃避沙箱的跟踪。

二、环境检测类

这一大类并没有很高的技术含量,就是检测环境,换句话说就是比谁脑洞大。这类检测方法往往不能直接断定沙箱,但是可以通过计算权重作为判断依据。

1)屏幕分辨率

检查屏幕分辨率是否是常用的分辨率,下面给出一个示例代码

void GetMonitorRealResolution(HMONITOR monitor, int* pixelsWidth, int* pixelsHeight)
{
    MONITORINFOEX info = { sizeof(MONITORINFOEX) };
    winrt::check_bool(GetMonitorInfo(monitor, &info));
    DEVMODE devmode = {};
    devmode.dmSize = sizeof(DEVMODE);
    winrt::check_bool(EnumDisplaySettings(info.szDevice, ENUM_CURRENT_SETTINGS, &devmode));
    *pixelsWidth = devmode.dmPelsWidth;
    *pixelsHeight = devmode.dmPelsHeight;
}

修改屏幕分辨率就可以很好的针对这种检测,现在应该很少有沙箱会犯这种低级错误。

2)首选语言

func IFlanguage() {
  a, _ := windows.GetUserPreferredUILanguages(windows.MUI_LANGUAGE_NAME) 
  if a[0] != "zh-CN" {
    os.Exit(1)
  }
}

正常情况下,我们接触到的都是国内项目,系统都是中文的,但是许多沙箱都是默认配置搭建起来的,所以使用英文系统。获取当前系统首选语言也是一种有效的检测方法。

3)主机用户/主机名

某些沙箱厂商会使用几个固定的用户名/主机名,在后面的信息搜集类模块会细讲。

4)注册表

不同的沙箱厂商会有一些特定的注册表路径,还有一些特殊的注册表项值。依旧以我们常见的Vmware举例:

图片

5)进程

可以细分为两个方向,一个是检测正常个人电脑不该有进程,比如Vmtoolsd.exe等。另一个是检测正常个人电脑该有的进程,比如微信、QQ、浏览器等。

这个方法可以更进一步的延伸,检测进程地址空间中有没有特定的libraries。比如sbiedll.dll、dbghelp.dll、api_log.dll、vmcheck.dll等。

6)最近文件

Win+R输入Recent就可以看到当前主机的最近文件,下图是一个正常使用的主机,满满的都是使用痕迹:

图片

如果最近文件夹中的数量少于n,那就可以断定这台主机大概率是沙箱。

7)临时文件

与最近文件同理。

8)特定文件

虚拟环境中存在一些真实环境中没有的文件,以Vmware举例。下面是一个真实主机:

图片

然后再看看虚拟机:

图片

很明显可以看到多了一些vm开头的文件。但不一定都能作为依据判断虚拟机,因为电脑只要装了Vmware这个工具,也会出现许多vm开头的文件,假如你选择了一个不恰当的文件作为依据,只能判断出这可能是一台虚拟机也可能是安装了Vmware的真实物理机。

9)特定目录

与特定文件同理。

10)上次开机时间

用过虚拟机的同学,应该都知道有一个很好用的功能就是快照,还原快照后会将当前虚拟机的状态还原到拍摄快照时的状态。而WMI数据库可能包含创建VM快照时的开机时间,如果快照是在一年前创建的,且沙箱仅更新了上次启动的时间,但是系统正常运行时间还是一年,这无疑是不合理的。

这一特性可以检测出从快照恢复的虚拟机,如果命中下面任何一条规则,都很可疑:

1.系统正常运行时间过长。

2.系统正常运行时间太短。(听说有的同学拿到样本现开虚拟机?)

3.多种方式获得的上次开机时间不一致。

11)CPU运行时间

具体原理见上一条,这里只给出一个简单的demo。

#define MIN_UPTIME_MINUTES 12
BOOL uptime_check()
{
    ULONGLONG uptime_minutes = GetTickCount64() / (60 * 1000);
    return uptime_minutes < MIN_UPTIME_MINUTES;
}

这里使用的API是不是很眼熟?所以绕过方式应该不用我多说了。

12)wifi检测

Windows虚拟机有一个特性,就是将所有网络连接识别为有线连接。所以一台没有任何WIFI连接记录的主机是很可疑的

实体机中执行命令 netsh wlan show profiles

图片

再在虚拟机中执行一下。

图片

区别还是很明显的,当然结果只能作为参考。

13)检查窗口数量

如果你经常使用的云沙箱,会发现返回测试截图的时候除了我们提交的文件,没有别的窗口存在。从性能角度考虑这是合理的,但同时提升了可疑性。

小结

环境检测类部分也讲完了,正如我在本段开头所说的,这里面很多方法只能判断这台主机可疑但是不能直接断定为沙箱,所以实战中最好多种方法复合使用。

一方面限于篇幅,另一方面也感觉自己还有许多没覆盖到的知识面,所以并没有一次性将内容写完。如果大佬们有独到的见解,新奇的脑洞,或者发现什么错误,欢迎私信默安逐日实验室公众号后台交流。

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

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

相关文章

Camunda Asynchronous continuations

示例一 Service public class ExceptionService implements JavaDelegate {Overridepublic void execute(DelegateExecution execution) {System.out.println(1/0);} }ACT_RU_TASK &#xff1a;明明是UserTask2完成任务了&#xff0c;ServiceTask内部出错了&#xff0c;按说事务…

什么是云服务器?云服务器的工作原理是介绍

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Kali Linux —— 漏洞分析工具

Cisco-torch与Global Exploiter专攻Cisco漏洞 一、Cisco 工具 Kali 有许多工具&#xff0c;比如信息收集工具、密码爆破工具等等&#xff0c;还有一些可用于攻击 Cisco 路由器的工具。Cisco-torch就是这样&#xff0c;用于大规模扫描、指纹识别和利用的工具之一。 打开终端控…

10 款适用于 Mac 的最佳 OCR 软件:高质量图片识别文字OCR

我们正处在无纸化办公渗透到我们工作中的时代&#xff0c;我们经常使用数字化文件。但是&#xff0c;我们很有可能需要进一步编辑这些不可编辑或不可搜索的文件以用于不同的目的。并应用 OCR 使这些扫描文件可编辑。对于 Mac 用户&#xff0c;使用适用于 Mac 的最佳 OCR 软件通…

WXUI 基于uni-app x开发的高性能混合UI库

uni-app x 是什么&#xff1f; uni-app x&#xff0c;是下一代 uni-app&#xff0c;是一个跨平台应用开发引擎。 uni-app x 没有使用js和webview&#xff0c;它基于 uts 语言。在App端&#xff0c;uts在iOS编译为swift、在Android编译为kotlin&#xff0c;完全达到了原生应用…

DrGraph原理示教 - OpenCV 4 功能 - 边界填充

今天简单来看一下OpenCV中的边界填充 param src Source image. param dst Destination image of the same type as src and the size Size(src.colsleftright, src.rowstopbottom) . param top the top pixels param bottom the bottom pixels param left the left pixels par…

Echarts的常用API,以及常用的写法

ECharts是一款基于JavaScript的开源可视化库&#xff0c;用于构建交互式的图表和可视化数据。它提供了丰富的API用于定制图表和处理数据。下面是一些常用的ECharts API和写法的简介&#xff1a; 初始化图表容器&#xff1a; var myChart echarts.init(document.getElementBy…

基于opencv的指针式仪表的识别与读数

对于指针式仪表的识别与读数&#xff0c;可以通过以下步骤使用OpenCV实现&#xff1a; 读取图像&#xff1a;使用cv2.imread()函数读取要处理的仪表图像。 灰度转换&#xff1a;使用cv2.cvtColor()函数将彩色图像转换为灰度图像。这是因为灰度图像只有一个通道&#xff0c;便…

告别信息差!奇点云SimbaMetric打破协作壁垒,为指标管理提效

谈到指标&#xff0c;相信每家企业都遇到过以下问题&#xff1a; 对指标的定义不清晰&#xff0c;必须跨部门反复沟通&#xff0c;新建、修改指标的成本高&#xff1b; 各种指标逻辑近似&#xff0c;但没有复用&#xff0c;数据团队有大量重复工作&#xff1b; 由于没有生…

argparse库

引言 argparse-------python用于解析命令行参数的标准模块 快速上手 import argparse parser argparse.ArgumentParser() 创建一个命令行解析器对象 parser.add_argument() 向解析器…

PHP留言板实现

完整教程PHP留言板 登陆界面 一个初学者的留言板&#xff08;登录和注册&#xff09;_php留言板登录注册-CSDN博客 留言板功能介绍 百度网盘 请输入提取码 进入百度网盘后&#xff0c;输入提取码&#xff1a;knxt&#xff0c;即可下载项目素材和游客访问页面的模板文件。 &…

TOP 10 屏幕录制软件工具,可帮您轻松录制视频!

随着越来越多的人远程工作和学习&#xff0c;对可靠、高效的屏幕录制工具的需求变得越来越重要。屏幕录制已成为电子学习、游戏和视频创作的重要组成部分。然而&#xff0c;有这么多可用的屏幕录制工具&#xff0c;选择合适的工具可能具有挑战性。为了帮助您节省搜索时间和精力…

权限系统模型:RBAC模型与ABAC模型

权限系统 基于角色的访问控制&#xff08;RBAC&#xff09; 基于角色的控制访问&#xff08;Role-Based Access Control&#xff0c;简称 RBAC&#xff09;&#xff0c;即&#xff1a;给予该账号角色&#xff08;Role&#xff09;&#xff0c;授权角色对应的相关权限&#xf…

0基础学习VR全景平台篇第137篇:720VR全景,DJI无人机遥控器调参

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 这节课以御2为例 介绍的是无人机调参 步骤一&#xff1a;下载DJI Go 4并注册账号 步骤二&#xff1a;拿下遥杆并装好&#xff0c;展开遥控天线。将无人机与遥控器相连&#xff…

什么是云服务器ECS - 云服务器 ECS - 阿里云

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

ChatGPT、Claude等聚合平台Poe,获7500万美元融资

1月11日&#xff0c;生成式AI聊天助手聚合平台Poe&#xff0c;获得7500万美元&#xff08;约5.3亿美元&#xff09;&#xff0c;估值5亿美元&#xff08;约35.8亿元&#xff09;。本次由 Andreessen Horowitz、a16z等投资。 Poe几乎聚合、镜像了目前市面上所有知名的文本、图片…

Easticsearch性能优化之硬件优化

Easticsearch性能优化之硬件优化 一、CPU配置二、内存配置1、内存配置总体方针2、内存实际分配3、禁止swap4、GC设置 三、IO&#xff08;磁盘&#xff09; 对于性能优化&#xff0c;升级硬件设备配置一直都是提高服务能力最快速有效的手段。硬件优化主要可以从CPU、内存、存储设…

数字孪生+可视化技术 构建智慧新能源汽车充电站监管平台

前言 充电基础设施为电动汽车提供充换电服务&#xff0c;是重要的交通能源融合类基础设施。近年来&#xff0c;随着新能源汽车产业快速发展&#xff0c;我国充电基础设施持续增长&#xff0c;已建成世界上数量最多、服务范围最广、品种类型最全的充电基础设施体系。着眼未来新…

【Matlab】在Matlab中安装优化工具yalmip的方法

最近博主想做一些关于多目标优化的问题&#xff0c;因为之前对Matlab有一定经验&#xff0c;所以直接在网上查找了如何在Matlab上实现多目标优化的文献&#xff0c;看到有人提到了yamip&#xff0c;于是博主就试着在Matlab中安装yamip&#xff0c;将其中遇到的问题和一些经验和…