API函数的调用过程(下)(ring0部分)

前言:内核函数 return,并不等于系统调用结束

在上一篇文章中,我们已经跟踪到:

call ebx;ebx=NtOpenProcess

这条指令意味着:

系统调用框架代码已经完成了所有“准备工作”,
CPU 正式进入了具体内核服务函数(如 NtOpenProcess)。

但一个非常容易被误解的点是:

内核函数 return ≠ 系统调用结束

事实上,在NtOpenProcess返回之后,
Windows 还要完成一整套“返回前校验 + APC 处理 + TrapFrame 回收 + Ring3 恢复”的流程。

这,正是本文要讲清楚的内容。

本文完整汇编代码如下:

.text:0043E1E8 loc_43E1E8:;CODE XREF:_KiFastCallEntry+4BB↓j.text:0043E1E8 call ebx;直接调用系统服务函数---------------------------.text:0043E1EA.text:0043E1EA loc_43E1EA:;CODE XREF:_KiFastCallEntry+334↓j.text:0043E1EA;DATA XREF:_KiTrap0E+18C↓o.text:0043E1EA test byte ptr[ebp+_KTRAP_FRAME.SegCs],1;判断来自r3还是r0.text:0043E1EE jzshortloc_43E224;如果来自r0,直接跳到“纯内核返回路径.text:0043E1F0 mov esi,eax;备份系统调用函数的返回值.text:0043E1F2 call ds:__imp__KeGetCurrentIrql@0;获取当前IRQL.text:0043E1F8oral,al.text:0043E1FA jnz loc_43E53B;返回r3的IRQL必须是0.text:0043E1FA;如果IRQL不等于0,就跳转蓝屏.text:0043E200mov eax,esi;恢复系统调用返回值.text:0043E202mov ecx,large fs:_KPCR.PrcbData.CurrentThread;ecx=当前正在运行的 KTHREAD.text:0043E209test[ecx+_KTHREAD.ApcStateIndex],0FFh;判断当前线程是否处于挂靠环境.text:0043E210jnz loc_43E559;如果处于挂靠环境,跳转蓝屏.text:0043E216mov edx,dword ptr[ecx+_KTHREAD.___u26.__s0.KernelApcDisable].text:0043E21Coredx,edx;如果KernelApcDisable=1.text:0043E21E jnz loc_43E559;跳转蓝屏.text:0043E224.text:0043E224loc_43E224:;CODE XREF:_KiFastCallEntry+12E↑j.text:0043E224;_KiCallbackReturn+8D↓j.text:0043E224;DATA XREF:....text:0043E224mov esp,ebp.text:0043E226cmp[ebp+_KTRAP_FRAME.Logging],0;记录函数调用后的日志.text:0043E226;检查 TrapFrame.Logging 决定走特殊分支.text:0043E22A jnz loc_43E580.text:0043E230.text:0043E230loc_43E230:;CODE XREF:_KiBBTUnexpectedRange+3C↑j.text:0043E230;_KiBBTUnexpectedRange+47↑j....text:0043E230mov ecx,large fs:_KPCR.PrcbData.CurrentThread.text:0043E237mov edx,[ebp+_KTRAP_FRAME._Edx];-若来自 Ring0:该字段保存的是嵌套调用前的 TrapFrame.text:0043E23A mov[ecx+_KTHREAD.TrapFrame],edx;恢复当前线程的 TrapFrame 指针.text:0043E23A _KiFastCallEntry endp;即:弹出当前系统调用的 TrapFrame.text:0043E23A.text:0043E240.text:0043E240;===============S U B R O U T I N E=======================================.text:0043E240.text:0043E240.text:0043E240_KiServiceExit proc near;CODE XREF:NtContinue(x,x)+43↓j.text:0043E240;NtRaiseException(x,x,x)+38↓j....text:0043E240.text:0043E240arg_C=word ptr10h.text:0043E240arg_10=dword ptr14h.text:0043E240arg_28=dword ptr2Ch.text:0043E240arg_40=dword ptr44h.text:0043E240arg_44=dword ptr48h.text:0043E240arg_48=dword ptr4Ch.text:0043E240arg_60=dword ptr64h.text:0043E240arg_64=dword ptr68h.text:0043E240arg_68=dword ptr6Ch.text:0043E240arg_6C=dword ptr70h.text:0043E240.text:0043E240;FUNCTION CHUNK AT.text:0043E35C SIZE00000089BYTES.text:0043E240.text:0043E240cli;关闭中断,因为要恢复现场.text:0043E241test byte ptr[ebp+(_KTRAP_FRAME.EFlags+2)],2;判断是否8086模式.text:0043E245jnzshortloc_43E24D;如果是虚拟8086模式跳走不执行下面代码.text:0043E247test byte ptr[ebp+_KTRAP_FRAME.SegCs],1;判断来自r0还是r3.text:0043E24B jzshortloc_43E2B4;如果来自r0就跳转.text:0043E24D.text:0043E24D loc_43E24D:;CODE XREF:_KiServiceExit+5↑j.text:0043E24D;_KiServiceExit+6F↓j.text:0043E24D mov ebx,large fs:_KPCR.PrcbData.CurrentThread.text:0043E254test[ebx+_KTHREAD.Header.___u0.__s0.ThreadControlFlags],2.text:0043E258jzshortloc_43E262.text:0043E25A push eax.text:0043E25B push ebx.text:0043E25C call _KiCopyCounters@4;性能统计.text:0043E261pop eax.text:0043E262.text:0043E262loc_43E262:;CODE XREF:_KiServiceExit+18↑j.text:0043E262mov[ebx+_KTHREAD.Alerted],0.text:0043E266cmp[ebx+_KTHREAD.___u12.ApcState.UserApcPending],0.text:0043E26A jzshortloc_43E2B4.text:0043E26C mov ebx,ebp;ebx=trap_frame.text:0043E26E mov[ebx+_KTRAP_FRAME._Eax],eax.text:0043E271mov[ebx+_KTRAP_FRAME.SegFs],3Bh;';'.text:0043E278mov[ebx+_KTRAP_FRAME.SegDs],23h;'#'.text:0043E27Fmov[ebx+_KTRAP_FRAME.SegEs],23h;'#'.text:0043E286mov[ebx+_KTRAP_FRAME.SegGs],0.text:0043E28D mov ecx,1;NewIrql.text:0043E292call ds:__imp_@KfRaiseIrql@4;KfRaiseIrql(x).text:0043E298push eax.text:0043E299sti.text:0043E29A push ebx;trap_frame.text:0043E29B push0;kexcep_frame.text:0043E29D push1;ApcMode.text:0043E29Fcall _KiDeliverApc@12;派发apc.text:0043E2A4 pop ecx;NewIrql.text:0043E2A5 call ds:__imp_@KfLowerIrql@4;KfLowerIrql(x).text:0043E2AB mov eax,[ebx+44h].text:0043E2AE cli.text:0043E2AF jmpshortloc_43E24D;循环执行apc,直到UserApcPending=0.text:0043E2AF;---------------------------------------------------------------------------.text:0043E2B1 align4.text:0043E2B4.text:0043E2B4 loc_43E2B4:;CODE XREF:_KiServiceExit+B↑j.text:0043E2B4;_KiServiceExit+2A↑j.text:0043E2B4 mov edx,[esp+_KTRAP_FRAME.ExceptionList];.text:0043E224有一条esp=ebp的命令所以,.text:0043E2B4;所以此处esp是trap_frame.text:0043E2B8 mov large fs:_KPCR,edx;还原现场.text:0043E2BF mov ecx,[esp+_KTRAP_FRAME.PreviousPreviousMode].text:0043E2C3 mov esi,large fs:_KPCR.PrcbData.CurrentThread.text:0043E2CA mov[esi+_KTHREAD.PreviousMode],cl;KTHREAD.PreviousMode=_KTRAP_FRAME.PreviousPreviousMode.text:0043E2D0 test[esp+_KTRAP_FRAME.Dr7],0FFFF23FFh.text:0043E2D8 jnz loc_43E35C.text:0043E2DE.text:0043E2DE loc_43E2DE:;CODE XREF:_KiServiceExit+12C↓j.text:0043E2DE;_KiServiceExit+15B↓j.text:0043E2DE test[esp+_KTRAP_FRAME.EFlags],20000h;判断是不是虚拟8086模式.text:0043E2E6 jnz loc_43ED2C;是虚拟8086模式就跳转.text:0043E2EC test word ptr[esp+_KTRAP_FRAME.SegCs],0FFF8h.text:0043E2F3 jz loc_43E3B2.text:0043E2F9 cmp word ptr[esp+_KTRAP_FRAME.SegCs],1Bh;判断cs是不是r3的.text:0043E2FFbt word ptr[esp+_KTRAP_FRAME.SegCs],0.text:0043E306cmc.text:0043E307ja loc_43E3A0;是r3的就跳.text:0043E30D cmp word ptr[ebp+_KTRAP_FRAME.SegCs],8.text:0043E312jzshortloc_43E319;如果是r3就跳转.text:0043E314.text:0043E314loc_43E314:;CODE XREF:_KiServiceExit+16D↓j.text:0043E314lea esp,[ebp+_KTRAP_FRAME.SegFs];让esp指向_KTRAP_FRAME.SegFs.text:0043E317pop fs.text:0043E319assume fs:nothing.text:0043E319.text:0043E319loc_43E319:;CODE XREF:_KiServiceExit+D2↑j.text:0043E319lea esp,[ebp+_KTRAP_FRAME._Edi];让esp指向_KTRAP_FRAME._Edi的位置.text:0043E31C pop edi;还原寄存器.text:0043E31D pop esi.text:0043E31E pop ebx.text:0043E31Fpop ebp.text:0043E320cmp word ptr[esp+8],80h;'€';esp+8的位置是_KTRAP_FRAME.SegCs.text:0043E327ja loc_43ED48;判断cs是不是8086模式的段,如果是就跳转.text:0043E32D add esp,4;此时esp指向_KTRAP_FRAME.Eip.text:0043E330test dword ptr[esp+4],1;再次判断_KTRAP_FRAME.SegCs是不是r3的段.text:0043E330_KiServiceExit endp;sp-analysis failed.text:0043E330.text:0043E338.text:0043E338_KiSystemCallExitBranch:;DATA XREF:KiRestoreFastSyscallReturnState():loc_412819↑r.text:0043E338;KiRestoreFastSyscallReturnState()+7D↑w....text:0043E338jnzshort_KiSystemCallExit;如果是r3跳转.text:0043E33A pop edx.text:0043E33B pop ecx.text:0043E33C popf.text:0043E33D jmp edx.text:0043E33F;---------------------------------------------------------------------------.text:0043E33F;START OF FUNCTION CHUNK FOR _KiSystemCallExit2.text:0043E33F.text:0043E33F_KiSystemCallExit:;CODE XREF:.text:_KiSystemCallExitBranch↑j.text:0043E33F;_KiSystemCallExit2+8↓j.text:0043E33F;DATA XREF:....text:0043E33Firet

一、call ebx 之后:系统调用的“返回检查阶段”

.text:0043E1E8 call ebx

从这一刻开始:

  • EAX = 系统调用返回值(NTSTATUS)

  • 当前线程仍处于:

    • Ring0

    • 使用当前线程的内核栈

    • KTHREAD.TrapFrame 有效

    • 中断已开启(sti 已执行)

    • 但 Windows 还不能立刻返回用户态。

原因只有一个:

返回 Ring3 是一件“高风险操作”,必须满足一系列严格条件。

1.1 判断这次系统调用来自 Ring3 还是 Ring0

.text:0043E1EA.text:0043E1EA test byte ptr[ebp+_KTRAP_FRAME.SegCs],1.text:0043E1EE jzshortloc_43E224

判断依据:

  • _KTRAP_FRAME.SegCs 的 RPL 位

  • bit0 = 1 → 来自 Ring3

  • bit0 = 0 → 来自 Ring0

如果 来自 Ring0:

不涉及用户态返回,
不需要 IRQL / APC / 上下文安全检查,
直接走“纯内核返回路径”。

1.2 返回 Ring3 前,必须满足的三个硬条件

如果这次系统调用来自 Ring3,代码继续执行:

.text:0043E1F0 mov esi,eax;备份系统调用函数的返回值.text:0043E1F2 call ds:__imp__KeGetCurrentIrql@0;获取当前IRQL.text:0043E1F8oral,al.text:0043E1FA jnz loc_43E53B;返回r3的IRQL必须是0.text:0043E1FA;如果IRQL不等于0,就跳转蓝屏.text:0043E200mov eax,esi;恢复系统调用返回值

条件一:IRQL 必须为 PASSIVE_LEVEL

返回用户态时,IRQL ≠ 0 是绝对非法的。

原因很简单:

  • 用户态代码允许:

    • 页面错误

    • APC

    • 抢占

  • 高 IRQL 下返回用户态 = 系统不再可控

因此:

只要 IRQL ≠ 0,立刻蓝屏。


.text:0043E202mov ecx,large fs:_KPCR.PrcbData.CurrentThread;ecx=当前正在运行的 KTHREAD.text:0043E209test[ecx+_KTHREAD.ApcStateIndex],0FFh;判断当前线程是否处于挂靠环境.text:0043E210jnz loc_43E559;如果处于挂靠环境,跳转蓝屏

条件二:线程不能处于 Attached APC 环境

如果线程:

  • 通过 KeStackAttachProcess

  • 切换到了其他进程的地址空间

那么:

当前 TrapFrame 对应的用户态上下文已经不再安全。

这种状态下返回 Ring3,属于严重内核错误直接蓝屏


.text:0043E216mov edx,dword ptr[ecx+_KTHREAD.___u26.__s0.KernelApcDisable].text:0043E21Coredx,edx;如果KernelApcDisable=1.text:0043E21E jnz loc_43E559;跳转蓝屏

条件三:Kernel APC 必须是可投递状态否则

如果:

  • KernelApcDisable ≠ 0

  • 说明线程当前不允许 APC

那么:

系统调用不能返回用户态
否则 APC 语义将被破坏,导致直接蓝屏

二、回收 TrapFrame,准备进入 KiServiceExit

在完成系统调用函数(如 NtOpenProcess)的执行之后,
执行流并不会立刻返回用户态。

相反,Windows 内核必须先完成一项非常关键的工作:

将当前线程的 TrapFrame 状态,恢复为“进入 sysenter 之前”的状态。

这一步,发生在下面这几条指令中。

2.1 执行流回到 TrapFrame 基址

.text:0043E224mov esp,ebp

这条指令意味着:

  • 当前执行流不再使用普通内核栈

  • ESP 被强制指向 当前系统调用构造的 KTRAP_FRAME

从这一刻开始:

接下来的所有操作,都是围绕 TrapFrame 的“回收与恢复”。


三、KiServiceExit:真正的“系统调用出口”

接下来执行的函数是:

_KiServiceExit

这是 Windows 中:

所有系统调用共享的“统一返回路径”

3.1 为什么一开始就 cli?

.text:0043E240cli;关闭中断,因为要恢复现场

原因非常明确:

恢复现场 ≠ 可中断操作

从这一刻开始:

  • 内核即将:

    • 恢复段寄存器

    • 恢复通用寄存器

    • 恢复 EFLAGS

    • 恢复 CS:EIP / SS:ESP

任何中断、异常:

都会直接破坏返回现场

3.2 User APC 的最后投递机会

.text:0043E266cmp[ebx+_KTHREAD.___u12.ApcState.UserApcPending],0.text:0043E26A jzshortloc_43E2B4

如果存在 User APC:

  • 当前线程即将返回 Ring3

  • 这是 最后一次合法投递 APC 的时机

于是内核:

.text:0043E29Fcall KiDeliverApc

这一步极其重要:

User APC 的执行点,严格发生在“系统调用返回用户态之前”。

四、真正的现场恢复:KTRAP_FRAME 的“反向消费”

接下来的代码,是对 TrapFrame 的逐字段反向恢复。


4.1 恢复 PreviousMode / 调试寄存器

.text:0043E2BF mov ecx,[esp+_KTRAP_FRAME.PreviousPreviousMode].text:0043E2C3 mov esi,large fs:_KPCR.PrcbData.CurrentThread.text:0043E2CA mov[esi+_KTHREAD.PreviousMode],cl;KTHREAD.PreviousMode=_KTRAP_FRAME.PreviousPreviousMode

含义:

  • 线程重新回到 UserMode

  • 内核不再以“内核信任模型”对待该线程


4.2 判断返回路径:iret 还是 fast path

.text:0043E30D cmp word ptr[ebp+SegCs],8

Windows 在这里区分:

  • 返回 Ring0 → Ring0

  • 返回 Ring0 → Ring3

  • 是否虚拟 8086 模式

  • 是否需要 iret


4.3 恢复通用寄存器

.text:0043E319pop edi.text:0043E31D pop esi.text:0043E31E pop ebx.text:0043E31Fpop ebp.text:0043E320cmp word ptr[esp+8],80h;'€';esp+8的位置是_KTRAP_FRAME.SegCs.text:0043E327ja loc_43ED48;判断cs是不是8086模式的段,如果是就跳转.text:0043E32D add esp,4;此时esp指向_KTRAP_FRAME.Eip.text:0043E330test dword ptr[esp+4],1;再次判断_KTRAP_FRAME.SegCs是不是r3的段.text:0043E338jnzshort_KiSystemCallExit;如果是r3跳转

KTRAP_FRAME 中保存的“被打断前寄存器”,已全部回到 CPU

我们还需要特别关注的是此时ESP指向_KTRAP_FRAME.Eip处

五、最终返回:为什么这里必须是 iret?

_KiSystemCallExit:iret

原因只有一个:

sysenter 没有返回指令

而 iret 能一次性恢复:

  • EIP

  • CS

  • EFLAGS

  • ESP

  • SS

这正是:KTRAP_FRAME 从一开始就必须完整保存这些字段的原因。

六、结语

至此,我们已经完整走完:

Ring3 ↓ sysenter KiFastCallEntry ↓ 构造 KTRAP_FRAME SSDT 查表 ↓ NtOpenProcess ↓returnKiServiceExit ↓ iret Ring3

也就是说:

系统调用真正的“入口”和“出口”,都发生在 Ring0。

而 KTRAP_FRAME:

  • 既是进入 Ring0 的“凭证”

  • 也是返回 Ring3 的“钥匙”

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

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

相关文章

分类器持续学习:云端自动更新模型版本

分类器持续学习:云端自动更新模型版本 引言 想象一下,你经营着一家电商平台,每天都有数百种新品上架。传统的商品分类系统需要人工打标、重新训练模型,每次更新都要停机维护,既影响用户体验又增加运营成本。现在&…

跨平台AI分类方案:Windows/Mac/Linux全支持,云端运行

跨平台AI分类方案:Windows/Mac/Linux全支持,云端运行 引言:为什么需要跨平台AI分类方案? 作为一名自由职业者,你可能经常需要在不同设备间切换工作——咖啡馆用MacBook写方案,回家用Windows台式机处理图片…

小米应用商店ASO优化:3大核心位置助你提升关键词覆盖

在移动应用竞争日益激烈的今天,应用商店优化(ASO)成为每个开发者必须重视的环节。而在各大安卓市场中,小米应用商店以其庞大的用户基础和独特的后台功能,为开发者提供了更多关键词优化的可能性。本文将深入解析小米应用…

装车记数显示屏为物流出货环节提供精准数据支持

在现代物流供应链管理中,准确计数和实时监控是提高效率、降低成本的关键环节。传统的人工计数方式不仅效率低下,还容易出现数据错误,给企业带来不必要的损失。装车记数显示屏作为一种智能化解决方案,正在改变这一现状,…

视觉语音文本一体化处理|AutoGLM-Phone-9B多模态能力深度探索

视觉语音文本一体化处理|AutoGLM-Phone-9B多模态能力深度探索 随着移动智能设备对AI能力的需求日益增长,如何在资源受限的终端上实现高效、精准的多模态理解成为关键挑战。AutoGLM-Phone-9B作为一款专为移动端优化的90亿参数级大模型,融合视…

移动端多模态大模型部署实战|基于AutoGLM-Phone-9B高效推理

移动端多模态大模型部署实战|基于AutoGLM-Phone-9B高效推理 1. 引言:移动端多模态AI的落地挑战与突破 随着大语言模型(LLM)能力的持续进化,多模态理解与生成已成为智能终端的核心竞争力。然而,在资源受限…

中科数测研究院发现工业级MQTT协议组件--NanoMQ多个高危漏洞

近日,中科数测研究院在对工业级MQTT消息中间件NanoMQ的系统性安全测试中,连续发现3个可远程触发的高危漏洞,覆盖协议逻辑缺陷、越界读取、释放后使用(Use-After-Free)三大核心风险类型,严重威胁工业物联网&…

AI分类模型选择困难?云端AB测试轻松解决

AI分类模型选择困难?云端AB测试轻松解决 引言 在AI项目开发中,我们经常会遇到这样的困境:面对众多开源分类模型(如ResNet、EfficientNet、Vision Transformer等),团队成员各执己见,争论哪个模…

5个热门AI分类器对比:云端GPU 3小时全试遍,省下万元显卡钱

5个热门AI分类器对比:云端GPU 3小时全试遍,省下万元显卡钱 引言 作为一名开发者,当你需要为项目选择一个合适的AI分类模型时,可能会面临这样的困境:GitHub上五花八门的模型让人眼花缭乱,本地电脑显存又不…

如何高效部署AutoGLM-Phone-9B?一文掌握本地推理全流程

如何高效部署AutoGLM-Phone-9B?一文掌握本地推理全流程 1. AutoGLM-Phone-9B 模型概述与核心价值 1.1 多模态轻量化设计的技术背景 随着移动智能设备对AI能力需求的持续增长,传统大模型因高算力消耗和内存占用难以在资源受限终端上运行。AutoGLM-Phon…

基于HY-MT1.5大模型镜像,实现多语言实时精准互译

基于HY-MT1.5大模型镜像,实现多语言实时精准互译 1. 引言:多语言互译的现实挑战与技术演进 在全球化加速的今天,跨语言沟通已成为企业出海、科研协作、内容传播的核心需求。然而,传统翻译服务在延迟高、隐私风险大、成本昂贵等方…

医疗废物智能监测:技术如何守护我们的健康与环境

医疗废物管理是医疗卫生机构中至关重要的一环,不仅关系到医护人员的职业安全,更直接影响公共卫生和环境保护。随着物联网、大数据、智能传感等技术的发展,医疗废物的收集、转运、暂存和处置过程正逐步实现数字化、智能化、可追溯化。今天我们…

从下载到API调用|AutoGLM-Phone-9B全链路实操指南

从下载到API调用|AutoGLM-Phone-9B全链路实操指南 随着移动端AI应用的爆发式增长,轻量化、多模态的大语言模型成为边缘计算场景下的关键基础设施。AutoGLM-Phone-9B 正是在这一背景下诞生的一款专为移动设备优化的90亿参数级大模型,融合文本…

分类模型冷启动解决方案:云端小样本学习,数据不足也能用

分类模型冷启动解决方案:云端小样本学习,数据不足也能用 引言:创业公司的数据困境与破局之道 刚起步的创业公司常常面临这样的困境:新业务需要AI模型支持,但缺乏足够的标注数据。传统机器学习方法动辄需要成千上万的…

三电平有源电力滤波器:基于DSP28335的宝藏资料分享

三电平有源电力滤波器 全套软硬-件资料 基于DSP28335,两套 可以直接用的最近在电力电子领域探索,发现了超棒的三电平有源电力滤波器相关资源,必须来和大家唠唠。这次要讲的是基于DSP28335的三电平有源电力滤波器全套软硬件资料,而…

5个热门分类模型对比:云端GPU 3小时全试遍,成本不到10块

5个热门分类模型对比:云端GPU 3小时全试遍,成本不到10块 1. 为什么需要对比分类模型? 电商平台的商品分类是基础但关键的技术环节。一个好的分类模型能准确识别商品类别,提升搜索和推荐效果。但对于初创团队来说,面临…

AI分类器快速验证方案:云端GPU按小时付费,成本直降80%

AI分类器快速验证方案:云端GPU按小时付费,成本直降80% 引言:创业团队的AI试错困境 当你有一个绝妙的AI分类器创意时,最痛苦的事情是什么?不是算法设计,不是数据收集,而是还没开始验证商业可行…

老旧电脑重生:通过云端GPU运行最新AI分类器

老旧电脑重生:通过云端GPU运行最新AI分类器 引言 你是否还在用着5年前的老旧笔记本,看着各种炫酷的AI应用却只能望洋兴叹?别担心,即使你的电脑配置再低,也能通过云端GPU轻松运行最新的AI分类器。想象一下&#xff0c…

从零开始部署AutoGLM-Phone-9B|本地化私有部署与API调用全步骤详解

从零开始部署AutoGLM-Phone-9B|本地化私有部署与API调用全步骤详解 1. 教程目标与前置准备 本教程旨在为开发者提供一套完整、可落地的 AutoGLM-Phone-9B 模型本地私有化部署方案,涵盖环境配置、模型获取、服务启动、API调用及常见问题处理。通过本文&…

AI分类器API快速接入指南:1小时完成对接,按调用付费

AI分类器API快速接入指南:1小时完成对接,按调用付费 1. 为什么需要AI分类器API? 作为一名小程序开发者,你可能经常遇到这样的需求:用户上传的图片或文字需要自动分类。比如电商小程序需要区分服装款式,内…