某手sig3-ios算法 Chomper黑盒调用

Chomper-iOS界的Unidbg

最近在学习中发现一个Chomper框架,Chomper 是一个模拟执行iOS可执行文件的框架,类似于安卓端大名鼎鼎的Unidbg。

这篇文章使用Chomper模拟执行某手的sig3算法,初步熟悉该框架。这里只熟悉模拟执行步骤以及一些常见的hook操作、读取操作等。

框架搭建

chomper 使用python开发,这里直接使用pip安装 pip install chomper (mac的m系列芯片,可能需要再自己电脑编译unicorn并安装)

下载chomper中rootfs​ 放在项目录下 如下:

基础代码如下:

import os

from chomper import Chomper
from chomper.const import ARCH_ARM64, OS_IOS
from chomper.objc import ObjC
from chomper.utils import pyobj2nsobj
from chomper.os.ios.hooks import register_hook
from unicorn import arm64_const

base_path = os.path.abspath(os.path.dirname(__file__))


def trace_inst_callback(self, uc, address, size, user_data):
    for inst in self.cs.disasm_lite(uc.mem_read(address, size), 0):
        self.logger.info(
            f"Trace at {self.debug_symbol(address)}: {inst[-2]} {inst[-1]}"
        )

        message = ""
        for i in range(31):
            if message:
                message += ", "
            message += f"x{i}={hex(self.uc.reg_read(getattr(arm64_const, f'UC_ARM64_REG_X{i}')))}"
        self.logger.info(message)


Chomper.trace_inst_callback = trace_inst_callback #这里是用来trace代码
#加载ios基础库支持。
emu = Chomper(
    arch=ARCH_ARM64,
    os_type=OS_IOS,
    rootfs_path=os.path.join(base_path, "rootfs/ios"),
    enable_ui_kit=True, #开启ui_kit库支持,
)

objc = ObjC(emu)

某手核心算法调用

这里不再分析sig3怎么来的,以及如何构造的,如果需要请看兔哥公众号文章。https://mp.weixin.qq.com/s/JG56KxPC7s3oSvoGkQVBRQ

算法加载流程如下:根据frida-trace得

+[KWSecurity defaultInterface]
 22578 ms  -[KWSecurity atlasSign:/rest/app/square/home/mall/tab/dynamic/feed87fa757cb702565b6afa61de4f5f9617]
 22582 ms     | +[KWSecuritySignature atlasSignPlus:0x2852e18c0 isInner:0x0 sdkid:0x10eb67638 sdkName:0x10eb67638 ztconfigFilePath:0x10eb67638]
 22582 ms     |    | +[KWOpenSecurityGuardManager getInstance]
 22582 ms     |    | -[KWOpenSecurityGuardManager getSecureSignatureComp]
 22582 ms     |    |    | -[KWOpenSecurityGuardManager getComponent:0x0]
 22582 ms     |    |    |    | +[KWOpenComponentLibrary getInstance]
 22582 ms     |    |    |    | -[KWOpenComponentLibrary getComponent:0x0]
 22582 ms     |    |    |    |    | -[KWOpenComponentLibrary sdkDict]
 22582 ms     |    | +[KWOpenSecurityGuardParamContext createParamContextWithAppKey:d7b7d042-d4f2-4012-be60-d97ff2429c17 paramDict:nil requestType:0x1 input:{length = 75, bytes = 0x2f726573 742f6170 702f7371 75617265 ... 34663566 39363137 } wbindexKey:lD6We1E8i bInnerInvoke:0x0 sdkid: sdkName: ztconfigFilePath:]
 22589 ms     |    |    | -[KWOpenSecurityGuardParamContext setAppKey:0x100932dd8]
 22589 ms     |    |    | -[KWOpenSecurityGuardParamContext setWbindexKey:0x100932df8]
 22589 ms     |    |    | -[KWOpenSecurityGuardParamContext setParamDict:0x0]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setRequestType:0x1]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setInput:0x2876d4e70]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setOutput:nil]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setErrorCode:0x0]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setBInnerInvoke:0x0]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setSdkid:0x10eb67638]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setSdkname:0x10eb67638]
 22590 ms     |    |    | -[KWOpenSecurityGuardParamContext setZtconfigFilePath:0x10eb67638]
 22590 ms     |    | +[KWOpenSecurityGuardParamContext createParamContextWithAppKey ret:<KWOpenSecurityGuardParamContext: 0x285c9ba80>
 22591 ms     |    | -[KWOpenSecureSignatureComponent atlasSignPlus:0x285c9ba80]
 22591 ms     |    |    | +[KWOpenSecurityGuardManager getInstance]
 22591 ms     |    |    | -[KWOpenSecurityGuardManager isInitialize] 0x1
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext appKey]
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext bInnerInvoke]
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext input]
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext sdkid]
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext sdkname]
 22591 ms     |    |    | -[KWOpenSecurityGuardParamContext ztconfigFilePath]
 22591 ms     |    |    | -[KWOpenSecurityGuardManager callCoreCommand:0x28b2 appkey:0x100932dd8 type:0x0 payload:0x0 context:0x0 isInputDataWithHeader:0x0 isOutputDataShuffleHeader:0x0 bInnerInvoke:0x2876d4e70 inputData:0x10eb67638 cdid:0x0 privatekeyData:0x10eb67638 sdkid:0x10eb67638 sdkName:0x10eb67638 ztconfigFilePath:0x17171f0d0 completion:0x20414ec30]
 22592 ms     |    |    | -[KWOpenSecurityGuardManager callCoreCommand:ret d7b7d042-d4f2-4012-be60-d97ff2429c17
 22592 ms     |    |    | -[KWOpenSecurityGuardParamContext setOutput:{length = 48, bytes = 0x36373736 30393335 32666262 66313665 ... 32323365 33303236 }]
 22593 ms     |    |    | -[KWOpenSecurityGuardParamContext setErrorCode:0x1]
 22593 ms     |    | -[KWOpenSecurityGuardParamContext errorCode]
 22593 ms     |    | -[KWOpenSecurityGuardParamContext output] {length = 48, bytes = 0x36373736 30393335 32666262 66313665 ... 32323365 33303236 }
 22594 ms     |    | -[KWOpenSecurityGuardParamContext output] {length = 48, bytes = 0x36373736 30393335 32666262 66313665 ... 32323365 33303236 }
 22595 ms  WSecurity atlasSign ret 677609352fbbf16ef42f2c2d57deecf00fdd8252223e3026
加载某手安全算法Framework

某手的算法核心是在gifCommonFramework库中。砸壳拿到ipa,从framework中拿到该dylib,开始加载,如下代码就加载完了,是不是感觉很简单。

binary_path = "gifCommonFramework"
ks = emu.load_module(
    module_file=os.path.join(base_path, binary_path),
    exec_init_array=True,
    #trace_symbol_calls=True,#trace symbol符号
    #trace_inst=True,#trace code 
)
初始化安全SDK

如下代码,模拟调用oc的方法调用。

  1. oc中的+的符号可直接调用,类似安卓中的public static方法;-符号需要进行初始化动作之后才可以调用,类似安卓中的需要new才可以调用的方法。

安全SDK进行初始化,通过getInstance之后获取该地址,并使用该地址进行调用initSDK。这块还有一个hook操作。

def hook_retval(retval): #hook 修改返回值
    def decorator(uc, address, size, user_data):
        return retval

    return decorator

emu.add_interceptor(ks.base + 0x1387A8, hook_retval(0)) 

KWOpenSecurityGuardManager_addr = objc.msg_send("KWOpenSecurityGuardManager", "getInstance")
print(KWOpenSecurityGuardManager_addr)
objc.msg_send(KWOpenSecurityGuardManager_addr, "initSDK")
objc.msg_send(KWOpenSecurityGuardManager_addr, "setIsInitialize:", 1)

算法调用

根据frida-trace代码可得。atlasSignPlus传递的是KWOpenSecurityGuardParamContext createParamContextWithAppKey ​ 之后的地址。

 encrypt_str="加密信息"
 encrypt_addr = objc.msg_send("KWOpenSecurityGuardParamContext",
                                 "createParamContextWithAppKey:paramDict:requestType:input:wbindexKey:bInnerInvoke:sdkid:sdkName:ztconfigFilePath:",
                                 pyobj2nsobj(emu, "d7b7d042-d4f2-4012-be60-d97ff2429c17"),
                                 0,
                                 1,
                                 pyobj2nsobj(emu, encrypt_str.encode()),
                                 pyobj2nsobj(emu, "lD6We1E8i"), 0, pyobj2nsobj(emu, ""), pyobj2nsobj(emu, ""),
                                 pyobj2nsobj(emu, ""))
#这里原本不是这样调用的,我为了方便不再引入其他东西,使用了类似java的new 然后直接调用atlasSignPlus,
KWOpenSecureSignatureComponent = objc.msg_send("KWOpenSecureSignatureComponent", "alloc")
KWOpenSecureSignatureComponent_init = objc.msg_send(KWOpenSecureSignatureComponent, 'init')
result = objc.msg_send(KWOpenSecureSignatureComponent_init, "atlasSignPlus:", encrypt_addr) #这里传递的就是地址,直接传。
print(result)

这里KWOpenSecurityGuardParamContext createParamContextWithApp​的方法是+,那便可以直接调用。这里也仅仅是设置好需要加密的一些参数。

这里最后其实是出不了具体的结果的,这里还要感谢兔哥的trace代码,从trace代码中发现了如下图。

  1. pyobj2nsobj 用来将python类型转为oc类型,int 类型默认即可。
  2. pyobj2cfobj python类型转为oc的cf类型。
加入hook校验

hook 之后直接返回0 使对比结果正确。


emu.add_interceptor(ks.base + 0x18F8C8, hook_retval(0)) #这里对比d7b7d042-d4f2-4012-be60-d97ff2429c17
输出结果

output其实返回的是一个nsdata类型。根据frida-trace的代码。这里就是bytes为最后需要的

    error_code = objc.msg_send(result, "errorCode")
    print(error_code)
    output = objc.msg_send(result, "output")#这里是nsdata
    data_bytes = objc.msg_send(output, "bytes") #这里就是获取bytes
    # 4b5a08193cf6b70803030001a41524cc1f87ae7e1e121c0a
    print(emu.read_string(data_bytes)) #这里直接读取bytes为string
固定随机因子

这里主要是说 随机数 时间戳等

chomper/os/ios/syscall.py

handle_sys_gettimeofday

chomper/os/ios/hooks.py

hook_srandom​、hook_time​、hook_random

补环境

如下即可。其他复杂的操作,可以看下作者的仓库。

@register_hook("-[NSUserDefaults(NSUserDefaults) registerDefaults:]")
def hook_ns_user_defaults_register_defaults(uc, address, size, user_data):
    print("hook_ns_user_defaults_register_defaults")
    return 0
其他hook操作
#直接hook oc方法 并修改返回值为oc obj类型
emu.add_interceptor("-[NSBundle bundleIdentifier]", hook_retval(pyobj2nsobj(emu, "com.ceair.b2m")))
#hook 一个地址并修改返回值
emu.add_interceptor(byd.base + 0x103C984A4, hook_retval(1))
#跳过一个函数不执行
def hook_skip(uc, address, size, user_data):
    pass
emu.add_interceptor("-[NSBundle initWithPath:]", hook_skip)

#这也是hook 一个地址。
def hook_call_compare(uc, address, size, user_data):
    emu = user_data["emu"]
	return 0
emu.add_hook(ks.base + 0x121724, hook_call_compare)
主动调用操作

除了文章主动调用sig3的案例外,还有如下:

#主动调用symbol获取uuid
CFUUIDCreateString = emu.find_symbol("_CFUUIDCreateString").address 
cfu = emu.call_symbol("_CFUUIDCreate", 0, )
uuids = emu.call_symbol("_CFUUIDCreateString", 0, cfu)

#主动调用地址
a1 = emu.create_string("1")
a2 = emu.create_string(s)
a3 = len(s)
a4 = emu.create_string(str('1'))
a5 = emu.create_buffer(8)
a6 = emu.create_buffer(8)
a7 = emu.create_string("1123123123")
emu.call_address(dddd.base + 0x109322118, a1, a2, a3, a4, a5, a6, a7)
TraceCode

目前作者官方还没支持上,不过作者也给了一份代码。后续应该有,也有下断点debug,

trace开启代码如下:


from unicorn import arm64_const


def trace_inst_callback(self, uc, address, size, user_data):
    for inst in self.cs.disasm_lite(uc.mem_read(address, size), 0):
        self.logger.info(
            f"Trace at {self.debug_symbol(address)}: {inst[-2]} {inst[-1]}"
        )
        message = ""
        for i in range(31):
            if message:
                message += ", "
            message += f"x{i}={hex(self.uc.reg_read(getattr(arm64_const, f'UC_ARM64_REG_X{i}')))}"
        self.logger.info(message)


Chomper.trace_inst_callback = trace_inst_callback


效果如下:

ipa本身相关的信息读取

将ipa中的info.plist放在和二进制文件一起的位置即可,chomper会自动加载处理。主要涉及如下两个。


bundle_identifier = info_data["CFBundleIdentifier"]
bundle_executable = info_data["CFBundleExecutable"]

总结

本文主要是介绍Chomper的算法模拟执行,Chomper目前已经已经是能比较完整的模拟ios可执行文件执行的模拟器,在这块有非常大的优势。

以前安卓端有强势的unidbg,现在iOS也有Chomper了,后续等待作者持续更新,完善Chomper。强势推荐一波-> Chomper地址: https://github.com/sledgeh4w/chomper。

我这块也已经使用Chomper完成雅迪系列、某手的算法调用。后续也会有更多扩展。

算法代码:
import logging
import os

from chomper import Chomper
from chomper.const import ARCH_ARM64, OS_IOS
from chomper.objc import ObjC
from chomper.utils import pyobj2nsobj
from chomper.os.ios.hooks import register_hook

base_path = os.path.abspath(os.path.dirname(__file__))

log_format = "%(asctime)s - %(name)s - %(levelname)s: %(message)s"
logging.basicConfig(
    format=log_format,
    level=logging.INFO,
)

logger = logging.getLogger()

handler = logging.FileHandler('log_ks.txt', mode='w', encoding='utf-8')
handler.setLevel(logging.INFO)
handler.setFormatter(logging.Formatter(log_format))

console = logging.StreamHandler()
console.setLevel(logging.INFO)

logger.addHandler(handler)


def hook_retval(retval):
    def decorator(uc, address, size, user_data):
        return retval

    return decorator


@register_hook("-[NSUserDefaults(NSUserDefaults) registerDefaults:]")
def hook_ns_user_defaults_register_defaults(uc, address, size, user_data):
    print("hook_ns_user_defaults_register_defaults")
    return 0



def hook_call_compare(uc, address, size, user_data):
    emu = user_data["emu"]
    return 0


from unicorn import arm64_const


def trace_inst_callback(self, uc, address, size, user_data):
    for inst in self.cs.disasm_lite(uc.mem_read(address, size), 0):
        self.logger.info(
            f"Trace at {self.debug_symbol(address)}: {inst[-2]} {inst[-1]}"
        )
        message = ""
        for i in range(31):
            if message:
                message += ", "
            message += f"x{i}={hex(self.uc.reg_read(getattr(arm64_const, f'UC_ARM64_REG_X{i}')))}"
        self.logger.info(message)


Chomper.trace_inst_callback = trace_inst_callback

binary_path = "gifCommonFramework"
emu = Chomper(
    arch=ARCH_ARM64,
    os_type=OS_IOS,
    rootfs_path=os.path.join(base_path, "rootfs/ios"),
    # trace_symbol_calls=True,
)

ks = emu.load_module(
    module_file=os.path.join(base_path, binary_path),
    exec_init_array=True,
    trace_symbol_calls=True,
    trace_inst=True,
    # trace_symbol_calls=True
)
objc = ObjC(emu)

emu.add_interceptor(ks.base + 0x1387A8, hook_retval(0))
emu.add_interceptor(ks.base + 0x18F8C8, hook_retval(0))

KWOpenSecurityGuardManager_addr = objc.msg_send("KWOpenSecurityGuardManager", "getInstance")
print(KWOpenSecurityGuardManager_addr)
objc.msg_send(KWOpenSecurityGuardManager_addr, "initSDK")

objc.msg_send(KWOpenSecurityGuardManager_addr, "setIsInitialize:", 1)
# 这里根据frida-trace代码实际执行的构造
encrypt_str = input("enc:")
encrypt_addr = objc.msg_send("KWOpenSecurityGuardParamContext",
                             "createParamContextWithAppKey:paramDict:requestType:input:wbindexKey:bInnerInvoke:sdkid:sdkName:ztconfigFilePath:",
                             pyobj2nsobj(emu, "d7b7d042-d4f2-4012-be60-d97ff2429c17"),
                             0,
                             1,
                             pyobj2nsobj(emu, encrypt_str.encode()),
                             pyobj2nsobj(emu, "lD6We1E8i"), 0, pyobj2nsobj(emu, ""), pyobj2nsobj(emu, ""),
                             pyobj2nsobj(emu, ""))
KWOpenSecureSignatureComponent = objc.msg_send("KWOpenSecureSignatureComponent", "alloc")
KWOpenSecureSignatureComponent_init = objc.msg_send(KWOpenSecureSignatureComponent, 'init')
result = objc.msg_send(KWOpenSecureSignatureComponent_init, "atlasSignPlus:", encrypt_addr)
print(result)

error_code = objc.msg_send(result, "errorCode")
print(error_code)

output = objc.msg_send(result, "output")
data_bytes = objc.msg_send(output, "bytes")
print(emu.read_string(data_bytes))

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch 深度学习框架中 torch.cuda.empty_cache() 的妙用与注意事项

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 在使用 PyTorch 进行深度学习模型训练与调优过程中&#xff0c;torch.cuda.empty_cache() 方法作为一种高效工具被广泛采用&#xff1b;但其正确应用要求充分理解该方法的功能及最佳实践。下文将对该方…

巧用GitHub的CICD功能免费打包部署前端项目

近年来&#xff0c;随着前端技术的发展&#xff0c;前端项目的构建和打包过程变得越来越复杂&#xff0c;占用的资源也越来越多。我有一台云服务器&#xff0c;原本打算使用Docker进行部署&#xff0c;以简化操作流程。然而&#xff0c;只要执行sudo docker-compose -f deploy/…

配置Api自动生成

我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/TVlJdMgYLoDJrsxAwMgcCE14nxt 使用Springfox Swagger生成API&#xff0c;并导入Postman&#xff0c;完成API单元测试 Swagger: 是一套API定义的规范&#xff0c;按照这套规范的要求去定义接口及接口相关信息&#xff0c;再通过可…

【JMeter使用-2】JMeter中Java Request采样器的使用指南

Apache JMeter 是一款功能强大的性能测试工具&#xff0c;支持多种协议和测试场景。除了内置的采样器&#xff08;如HTTP请求、FTP请求等&#xff09;&#xff0c;JMeter还允许通过 Java Request采样器 调用自定义的Java代码&#xff0c;从而实现更复杂的测试逻辑。本文将详细介…

将Google文档导入WordPress:简单实用的几种方法

Google文档是内容创作者非常实用的写作工具。它支持在线编辑、多人协作&#xff0c;并能够自动保存内容。但当我们想把Google文档中的内容导入WordPress网站时&#xff0c;可能会遇到一些小麻烦&#xff0c;比如格式错乱、图片丢失等问题。本文将为大家介绍几种简单实用的方法&…

Android开发-深入解析Android中的AIDL及其应用场景

深入解析 Android 中的 AIDL 及其应用场景 1. 前言2. AIDL 的核心概念3. AIDL 的实现步骤3.1. 定义 AIDL 接口文件3.2. 实现服务端&#xff08;Service&#xff09;3.3. 客户端绑定与调用 4. AIDL 的典型应用场景4.1. 多进程应用4.2. 与系统服务交互4.3. 高性能 IPC4.4. 跨应用…

PWM(脉宽调制)技术详解:从基础到应用实践示例

PWM&#xff08;脉宽调制&#xff09;技术详解&#xff1a;从基础到应用实践示例 目录 PWM&#xff08;脉宽调制&#xff09;技术详解&#xff1a;从基础到应用实践示例学前思考&#xff1a;一、PWM概述二、PWM的基本原理三、PWM的应用场景四、PWM的硬件配置与使用五、PWM的编程…

谷粒商城—分布式高级②.md

认证服务 1. 环境搭建 创建gulimall-auth-server模块,导依赖,引入login.html和reg.html,并把静态资源放到nginx的static目录下 2. 注册功能 (1) 验证码倒计时 //点击发送验证码按钮触发下面函数 $("#sendCode").click(function () {//如果有disabled,说明最近…

Nginx(详解以及如何使用)

目录 1. 什么是Nginx&#xff1f; 2. 为什么使用nginx? 3. 安装nginx 3.1?安装nginx的依赖插件 3.2 下载nginx ?3.3?创建一个目录作为nginx的安装路径 ?3.4?解压 ?3.5?进入解压后的目录 3.6?指定nginx的安装路径 ?3.7?编译和安装nginx 3.8 启动nginx ?…

STM32 HAL库标准库+ESP8266+机智云

前言 最近在项目中需要云平台对接&#xff0c;前面使用的是阿里云物理平台&#xff0c;具体开发可以看看我的这个文章&#xff1a;手把手教会使用阿里云平台&#xff0c;不过好像没有可以在手机很方便打开连接的&#xff0c;所以我在网上找到一些资料&#xff0c;发现机智云是…

【前端框架】Vue3 面试题深度解析

本文详细讲解了VUE3相关的面试题&#xff0c;从基础到进阶到高级&#xff0c;分别都有涉及&#xff0c;希望对你有所帮助&#xff01; 基础题目 1. 简述 Vue3 与 Vue2 相比有哪些主要变化&#xff1f; 答案&#xff1a; 响应式系统&#xff1a;Vue2 使用 Object.definePrope…

DarkLabel 2.4使用指南:高效标注视频数据目标检测标签

工具概述 DarkLabel 2.4 是一款强大的多功能标注工具&#xff0c;专为计算机视觉开发者设计&#xff0c;旨在提升标注工作的效率和精确度。其智能标注引擎支持两项核心功能&#xff1a;线性插值标注与多目标跟踪&#xff0c;极大地优化了视频标注过程。 &#xff08;1&#x…

js解析后端传来的如图示的list集合,怎么获取每个map的key和value

如图示&#xff0c;后端传到前端的questTypeList是一个HashMap的list集合 使用c标签将传来的集合放到下拉单选框中&#xff0c; <% taglib prefix"c" uri"http://java.sun.com/jsp/jstl/core" %><html> <body><form action"yo…

SpringSecurity请求流转的本质

1. SpringSecurity核心源码分析 分析SpringSecurity的核心原理,那么我们从哪开始分析?以及我们要分析哪些内容? 系统启动的时候SpringSecurity做了哪些事情?第一次请求执行的流程是什么?SpringSecurity中的认证流程是怎么样的?1.1 系统启动 当我们的Web服务启动的时候,…

[论文阅读] SeeSR: Towards Semantics-Aware Real-World Image Super-Resolution

文章目录 一、前言二、主要贡献三、Introduction四、Methodology4.1 Motivation &#xff1a;4.2Framework Overview.** 一、前言 通信作者是香港理工大学 & OPPO研究所的张磊教授&#xff0c;也是图像超分ISR的一个大牛了。 论文如下 SeeSR: Towards Semantics-Aware Rea…

在VS中通过vcpkg包管理器来安装使用qt5

常用指令 .\vcpkg install 库名 .\vcpkg install 库名版本号.\vcpkg install 库名 --trip x86-windows.\vcpkg list.\vcpkg search 库名 .\vcpkg x-all-installed --7zip PS G:\vcpkg> .\vcpkg help usage: vcpkg <command> [--switches] [--optionsvalues] [argume…

ESXI 8.0 linux vSphere Client service has stopped working.手动启动服务

1、首先在你的esxi中进入到你的VC系统中&#xff0c;我这个是linux部署 #查看每个服务及状态 service-control --status2、你会发现有停止的服务和正在启动的&#xff0c;在不知道具体哪些服务具体负责的功能&#xff0c;那你就一个一个起&#xff0c;边起边试----重要服务我后…

基于SpringBoot+Vue的装修装潢管理系统的设计与实现

获取源码&#xff1a;SpringBootVue的装修装潢公司管理系统: 用户&#xff1a;登录、注册、忘记密码、首页、产品展示、装修案例、装修套餐、装修预约、新闻动态、合作伙伴、在线留言、我的装修、个人中心、我的留言、我的预约、关于我们等功能管理员&#xff1a;登录、首页、户…

DeepSeek部署到本地(解决ollama模型下载失败问题)

一、下载ollama软件安装 1、下载ollama软件 Ollama 下载完成后可以直接进行安装&#xff08;外网&#xff0c;速度可能会有点慢&#xff09; 2、修改安装目录 进去下载的目录&#xff0c;使用cmd打开终端输入OllamaSetup.exe /DIRE:\MySoftware\Ollama 输入完成后会自动打开…

【拥抱AI】GPT Researcher的诞生

一、GPT Researcher 研究过程总结 GPT Researcher 是一个开源的自主智能体&#xff0c;旨在通过利用人工智能技术实现高效、全面且客观的在线研究。它通过一系列创新的设计和优化&#xff0c;解决了传统研究工具&#xff08;如 AutoGPT&#xff09;中存在的问题&#xff0c;如…