Frida实战:深入解析Android SSL Pinning绕过原理与Hook脚本编写
1. 项目概述为什么我们还在和SSL Pinning“斗智斗勇”搞Android安全测试或者逆向分析的朋友对“SSL Pinning”这个词肯定不陌生甚至有点“又爱又恨”。爱的是它作为一项重要的安全加固措施能有效防止中间人攻击保护用户数据不被窃听或篡改这是现代App安全架构的基石。恨的是当我们作为安全研究员、逆向工程师或者只是想深入了解一下某个App的网络通信逻辑时它就成了横在面前的一堵高墙。你抓包工具像Charles、Fiddler配置得再好系统证书装得再全一打开目标App网络请求要么直接失败要么返回一堆乱码日志里赫然写着“Certificate verification failed”。这就是SSL Pinning在起作用App不再完全信任操作系统或用户提供的根证书链而是将服务端证书的特定信息如公钥哈希硬编码或动态验证在代码里只有匹配的证书才能建立连接。所以“绕过SSL Pinning”就成了移动安全领域一个经典且持久的课题。市面上方法很多从早期简单的Xposed模块到后来基于各种注入框架的Hook方案。而Frida凭借其动态注入、脚本化、跨平台的强大特性成为了当前最主流、最灵活的解决方案之一。今天这篇实战我们就聚焦于使用Frida进行SSL Pinning绕过但不止步于“能用”我们要深入“为什么能用”以及“怎么用得稳”。网上很多教程只给脚本不讲原理遇到环境差异或App更新就抓瞎。我将结合多次实战踩坑的经验带你从原理到实践从通用方法到定制化对抗彻底掌握这套“破壁”之术。无论你是安全测试人员、逆向爱好者还是想了解App安全机制的开发者这篇长文都能给你带来实实在在的干货。2. SSL Pinning的核心原理与Frida的对抗哲学在动手之前我们必须先搞清楚对手的“武功路数”。SSL Pinning的实现并非铁板一块它在Android上有多种常见的“招式”我们的Hook策略也需要对症下药。2.1 SSL Pinning的常见实现方式Android应用实现证书绑定的地方主要在网络库和HTTP客户端层。以下是几种主流方式OkHttp的CertificatePinner这是目前最主流、最规范的方式。OkHttp库提供了CertificatePinner类开发者可以很方便地配置一个或多个主机名与预期证书公钥的SHA-256哈希的绑定关系。这是“官方推荐”的姿势。Apache HttpClient的自定义TrustManager一些老项目或底层库可能使用Apache HttpClient。开发者会实现一个自定义的X509TrustManager在checkServerTrusted方法中加入对特定证书的校验逻辑。自定义SSLSocketFactory或TrustManager更为底层和定制的做法。App可能完全自己实现SSLSocketFactory或者在初始化时替换掉默认的TrustManager从而完全掌控证书验证流程。Native层的验证C/C为了增加逆向难度核心校验逻辑可能放在Native层so库中。通过JNI调用在C/C代码里完成证书的解析与比对这给动态Hook带来了新的挑战。第三方SDK或网络库的集成像腾讯的MMTLS、阿里云的HTTPDNSSSL等它们可能内置了自己的证书校验逻辑形态各异。2.2 Frida的对抗策略总览Frida的核心能力在于动态插桩Instrumentation。我们不需要修改App的安装包APK而是在App运行时将我们的JavaScript代码注入到目标进程的内存空间中去修改关键函数的行为。对于SSL Pinning我们的核心攻击面就是那些负责证书验证的类和方法。策略可以归结为两类“使其信任一切”策略这是最粗暴也最通用的方法。我们Hook住证书验证链条中最关键的那些方法如TrustManager.checkServerTrusted,X509TrustManager.checkServerTrusted让它们不做任何校验直接通过或者返回一个空的异常列表。相当于给验证机制“开了后门”。“偷梁换柱”策略这种方法更为精细。我们依然让验证流程执行但在执行过程中将待验证的证书即我们抓包工具提供的证书的关键信息如公钥哈希替换成App预期中的那个值。或者直接Hook哈希计算函数让它始终返回App预期的哈希值。这种方法对抗一些会检测验证流程是否被短路的应用可能更有效。在本教程中我们将重点讲解第一种策略因为它适用性最广脚本最成熟。同时我们也会探讨如何应对第二种策略中的一些复杂情况以及当遇到Native层验证时该如何拓展思路。3. 实战环境搭建与前置检查工欲善其事必先利其器。一个稳定的Frida环境是成功的一半。很多新手卡在第一步问题都出在环境上。3.1 Frida环境部署详解你需要准备两部分客户端你的电脑和服务器端Android设备/模拟器。客户端PC/Mac# 使用Python的pip安装强烈建议在虚拟环境中进行 pip install frida-tools # 安装完成后验证版本 frida --version注意frida-tools版本最好与服务器端的frida-server版本保持一致或接近大版本号如16.x一致为佳可以避免很多RPC协议不兼容的问题。服务器端Android确定架构在设备上执行adb shell getprop ro.product.cpu.abi常见输出有arm64-v8a,armeabi-v7a,x86_64等。下载对应版本的frida-server前往Frida的GitHub Releases页面下载与你设备架构和客户端frida版本匹配的frida-server-*.xz文件。例如对于Android arm64和设备端应下载frida-server-16.1.4-android-arm64.xz。推送并启动# 解压下载的.xz文件得到frida-server文件 xz -d frida-server-*.xz # 推送至设备 adb push frida-server /data/local/tmp/ # 进入adb shell赋予执行权限以后台方式运行 adb shell cd /data/local/tmp chmod 755 frida-server ./frida-server 验证连接在电脑终端执行frida-ps -U如果能看到设备上运行的进程列表恭喜你环境通了。3.2 目标App与抓包工具准备目标App选择一个你熟悉的、已知启用了SSL Pinning的应用进行测试。切勿在未经授权的生产环境应用上进行测试。抓包工具推荐使用Charles Proxy或mitmproxy。确保你的电脑和手机处于同一局域网并在手机上配置好代理同时将抓包工具的根证书安装到手机的系统证书目录Android 7.0以上需要将证书安装到系统分区或对目标App进行额外配置以信任用户证书。关键前置检查 在尝试Hook之前先不做任何处理直接用配置好代理的手机打开目标App观察抓包工具。如果所有网络请求都失败或证书错误基本确认SSL Pinning存在。这是我们的基准状态。4. 核心Hook脚本解析与逐行精讲网上流传着很多“万能”的Frida SSL Pinning绕过脚本。直接拿来用可能偶尔成功但更可能失败。理解每一行代码的作用才能灵活调整应对变化。下面我们拆解一个功能强大、层次分明的脚本。4.1 脚本骨架与通用Hook点我们先看一个综合性的脚本框架它尝试了多个常见的Hook点Java.perform(function () { console.log([*] Starting SSL Pinning Bypass...); // 1. 信任所有证书的万能TrustManager var TrustManager Java.use(javax.net.ssl.X509TrustManager); var TrustManagerImpl Java.registerClass({ name: com.bypass.TrustManagerImpl, implements: [TrustManager], methods: { checkClientTrusted: function (chain, authType) {}, checkServerTrusted: function (chain, authType) {}, getAcceptedIssuers: function () { return []; } } }); var SSLContext Java.use(javax.net.ssl.SSLContext); SSLContext.init.overload([Ljavax.net.ssl.KeyManager;, [Ljavax.net.ssl.TrustManager;, java.security.SecureRandom).implementation function (keyManagers, trustManagers, secureRandom) { console.log([] SSLContext.init() hooked!); // 替换传入的TrustManager为我们自己实现的、什么都不校验的那个 var myTrustManager TrustManagerImpl.$new(); this.init(keyManagers, [myTrustManager], secureRandom); }; // 2. 针对OkHttp的CertificatePinner try { var CertificatePinner Java.use(okhttp3.CertificatePinner); CertificatePinner.check.overload(java.lang.String, java.util.List).implementation function (hostname, pins) { console.log([] Bypassing OkHttp CertificatePinner for: hostname); // 直接不执行任何检查让验证通过 return; }; // 另一个常见方法findMatchingPins CertificatePinner.findMatchingPins.overload(java.lang.String).implementation function (hostname) { console.log([] Bypassing OkHttp CertificatePinner.findMatchingPins for: hostname); return Java.use(java.util.Collections).emptyList(); }; } catch (e) { console.log([-] OkHttp CertificatePinner not found: e.message); } // 3. 针对Apache HttpClient的TrustManager try { var X509TrustManager Java.use(org.apache.http.conn.ssl.X509TrustManager); X509TrustManager.checkServerTrusted.implementation function (chain, authType) { console.log([] Bypassing Apache HttpClient X509TrustManager); // 空实现等同于信任所有 }; } catch (e) { console.log([-] Apache HttpClient X509TrustManager not found: e.message); } // 4. Hook常见的证书验证方法更底层 var X509Certificate Java.use(java.security.cert.X509Certificate); // 可以Hook verify等方法但通常不需要因为上面已经釜底抽薪 console.log([*] SSL Pinning Bypass hooks installed.); });4.2 关键代码段深度剖析1. 自定义TrustManager (Java.registerClass) 这是脚本中最核心、最彻底的一环。它没有去修改App原有的TrustManager而是重新创建了一个新的类这个类实现了X509TrustManager接口但它的checkServerTrusted和checkClientTrusted方法都是空的。当Hook到SSLContext.init方法时这是SSL上下文初始化的必经之路我们用这个“傀儡”TrustManager替换掉App原本想要使用的那个。这样一来后续所有的证书验证都会走到我们这个空方法里自然全部通过。实操心得这种方法非常强大但有些加固或检测手段会校验TrustManager的类名或实例。如果遇到Hook后仍失败的情况可以尝试不替换而是直接修改原TrustManager实例的方法实现使用.implementation但前提是你能找到那个具体的实例。2. OkHttpCertificatePinner的Hook OkHttp的绑定逻辑主要在check方法里。我们直接让它的实现为空验证就跳过了。findMatchingPins方法返回一个空列表也能达到类似效果。这里用了try...catch包裹因为不是所有App都用OkHttp找不到类很正常避免脚本因异常而终止。注意事项有些App可能会在代码里缓存CertificatePinner的检查结果或者使用CertificatePinner.Builder的build方法返回一个不可修改的实例。如果Hook了check方法仍无效可以尝试HookCertificatePinner.Builder的build方法返回一个我们自定义的、被Hook过的CertificatePinner实例。3. 方法重载Overload的处理 注意CertificatePinner.check.overload(java.lang.String, java.util.List)。在Java中方法可能有多个重载版本参数不同。Frida需要明确知道你要Hook哪一个。使用.overload并指定参数类型的签名来精确匹配。如何知道签名可以通过Frida的-j参数先枚举类的方法或者查看反编译的代码。4. 执行脚本 将上述代码保存为bypass_ssl.js然后使用Frida命令注入到目标进程# 附加到已运行的应用 frida -U -l bypass_ssl.js -f com.example.targetapp --no-pause # 或者以spawn方式启动应用 frida -U -l bypass_ssl.js -f com.example.targetapp注入成功后再操作App观察抓包工具应该能看到之前失败的HTTPS请求现在可以正常捕获和解密了。5. 进阶对抗与疑难问题排查如果你的通用脚本不起作用那么真正的挑战才刚刚开始。下面是一些进阶场景和排查思路。5.1 应对App的Anti-Frida检测越来越多的安全敏感型App会检测Frida的存在。常见检测点检测frida-server端口默认端口27042。检测进程名/内存映射查找包含“frida”字样的线程或内存模块。检测异常指令Frida的插桩会修改代码可能被检测。对抗措施修改Frida Server端口启动时指定非默认端口./frida-server -l 0.0.0.0:8080连接时使用frida -H 192.168.x.x:8080 ...。使用隐蔽模式Frida的Gadget模式可以将Frida库打包进App而不是外部注入但需要修改APK。动态Hook对抗代码写Frida脚本去Hook App内部的检测函数让它们总是返回“未检测到”的结果。这需要你先逆向分析出检测逻辑在哪里。使用其他工具辅助对于纯检测端口的可以尝试先用iptables重定向端口。5.2 处理Native层C/C的SSL Pinning当证书校验发生在so库里时就需要用到Frida的Interceptor来Hook Native函数。思路定位关键函数使用objdump、IDA Pro或Ghidra静态分析so库寻找与SSL相关的函数如SSL_CTX_set_cert_verify_callback,X509_verify_cert等来自OpenSSL库或自定义的JNI_OnLoad、Java_*函数。使用Frida的Native HookInterceptor.attach(Module.findExportByName(libtarget.so, SSL_verify_cert), { onEnter: function(args) { console.log([Native] SSL_verify_cert called); }, onLeave: function(retval) { // 强制让验证成功例如让函数返回1成功 retval.replace(1); console.log([Native] SSL_verify_cert bypassed, retval - 1); } });寻找Java到Native的桥梁App通常通过JNI调用Native函数。可以先在Java层找到加载so库System.loadLibrary和声明native方法的地方然后跟踪到具体的Native实现。5.3 脚本注入成功但抓包仍失败的排查清单按照以下步骤系统性排查步骤检查项可能原因与解决方案1. 基础连接frida-ps -U能否列出进程Frida-server未运行、版本不匹配、USB调试未开启、设备未授权。2. 脚本注入控制台是否有[*] Starting SSL Pinning Bypass...和[*] ... hooks installed.输出脚本语法错误、目标类不存在try-catch已处理、注入时机过早/过晚。尝试用-fspawn方式或确保App在主页后再附加。3. Hook生效当触发网络请求时控制台是否有[] Bypassing ...等日志输出Hook点不对。App可能使用了你没Hook的网络库如Cronet、腾讯MMTLS。需反编译分析其网络栈。4. 证书信任Hook已触发但Charles仍显示SSL handshake failed。我们的TrustManager可能没被调用到或者存在多层SSL上下文。尝试Hook更底层的TrustManagerFactory或所有X509TrustManager的实现类。5. 代理设置非SSL请求能抓HTTPS不行。手机代理设置正确吗Charles/mitmproxy的根证书安装并信任了吗Android 7 需注意系统级证书6. App自身行为抓包成功一次后后续请求又失败。App可能实现了证书锁定公钥轮换或每次连接都重新初始化SSL上下文并校验。需要Hook更初始化的地方或脚本实现更持久化的绕过。7. 加固混淆类名和方法名是混淆的如a.a, b.c。通用脚本失效。需要静态分析找到混淆后的对应类和方法名更新到脚本中。关注SSLContext、X509TrustManager、CertificatePinner等关键词的混淆映射。5.4 使用Objection进行快速测试如果你想要一个更快捷、无需写脚本的初步测试可以使用基于Frida的自动化工具Objection。# 安装 pip install objection # 连接设备探索目标App objection -g com.example.targetapp explore # 在Objection REPL中运行SSL Pinning绕过命令 android sslpinning disableObjection会自动尝试多种常见的绕过方法。它的优点是快缺点是黑盒、不够灵活对于定制化强的Pinning可能无效。但它是一个很好的初步诊断工具。如果Objection能成功说明是通用Pinning你可以再用Frida脚本细化如果Objection失败那你很可能需要走上文提到的深度分析之路。6. 实战案例逆向分析定制化Pinning并编写针对性脚本假设我们遇到一个App通用脚本无效Objection也失败了。我们需要进行手动逆向分析。步骤一静态分析找线索使用jadx-gui或APKTooldex2jar反编译APK。在代码中搜索关键词CertificatePinner,X509TrustManager,SSLContext,checkServerTrusted,TrustManager。重点关注网络请求初始化相关的类或者应用自定义的Application或NetworkSecurityConfig。步骤二动态追踪定目标如果静态分析找不到明显线索可能被混淆使用Frida进行动态追踪。写一个脚本跟踪所有X509TrustManager实现类的checkServerTrusted方法调用Java.perform(function() { // 枚举所有已加载的类 Java.enumerateLoadedClasses({ onMatch: function(className) { if (className.includes(TrustManager) || className.includes(X509)) { console.log([*] Found class: className); // 尝试Hook这个类的checkServerTrusted try { var clazz Java.use(className); var methods clazz.class.getDeclaredMethods(); for (var i in methods) { if (methods[i].getName().indexOf(checkServerTrusted) ! -1) { console.log([!] Potential target: className . methods[i].getName()); // 这里可以进一步尝试Hook但注意重载 } } } catch (e) {} } }, onComplete: function() {} }); });运行App并触发网络请求观察控制台输出找到被调用的那个具体的、混淆后的类和方法。步骤三编写针对性Hook脚本假设通过动态追踪我们发现实际负责校验的类是一个混淆后的com.sec.a.b.c其中有一个方法a(String, List)被调用。Java.perform(function () { var TargetClass Java.use(com.sec.a.b.c); TargetClass.a.overload(java.lang.String, java.util.List).implementation function(host, certs) { console.log([] Bypassing custom pinning in com.sec.a.b.c.a() for host: host); // 什么也不做直接返回 return; }; console.log([*] Custom pinning hook installed.); });这个脚本就是针对这个特定App的“特效药”。7. 总结与安全研究伦理通过以上从原理到实践从通用到定制的讲解你应该对使用Frida绕过Android SSL Pinning有了一个全面且深入的理解。关键在于理解原理、灵活运用、耐心排查。没有一成不变的脚本只有对机制的理解和解决问题的思路。最后必须强调安全研究的伦理与法律边界。本文所有技术仅限用于对自己拥有合法权限的移动应用进行安全评估。学习、研究移动安全技术。在CTF比赛等合法授权场景中使用。严禁将这些技术用于任何未经授权的网络攻击、数据窃取、隐私侵犯或商业破坏活动。在测试任何应用前请务必确保你已获得明确授权或在完全隔离的、属于自己的测试环境中进行。技术的力量来源于人也取决于人如何使用它。希望你能利用这些知识为构建更安全的移动生态贡献力量而非破坏它。在探索技术深度的同时永远不要忘记法律的准绳和道德的底线。

相关新闻

Three.js 3D 渲染与赛博朋克风格 UI 实现:从着色器到霓虹矩阵

Three.js 3D 渲染与赛博朋克风格 UI 实现:从着色器到霓虹矩阵

Three.js 3D 渲染与赛博朋克风格 UI 实现:从着色器到霓虹矩阵一、Web 3D 的"赛博觉醒":为什么前端需要第三维度 Web 页面长期被困在二维平面里。CSS 动画再炫,也只是平面的位移和变换。当你的 DApp 需要展示链上数据的三维可视化&a…

2026/6/22 7:51:37阅读更多 →
Qwen3 VL Instruct的思维链能力解析:Prompt、解码与视觉编码协同机制

Qwen3 VL Instruct的思维链能力解析:Prompt、解码与视觉编码协同机制

1. 项目概述:Qwen3 VL Instruct 模型的“思考”能力到底指什么最近在多个技术社区和本地部署交流群里,频繁看到“Qwen3 VL Instruct 会不会 think”这个提问。它不像一句简单的功能询问,更像一个带着困惑、试探甚至一点调侃的行业切口——背后…

2026/6/22 7:51:37阅读更多 →
Seedance 2.0:AI视频生成的节奏工程范式

Seedance 2.0:AI视频生成的节奏工程范式

1. Seedance 2.0 不是“下载软件”,而是即梦平台的全新AI视频生成模式很多人在搜索“Seedance 2.0在哪里下载”时,第一反应是找一个独立安装包——这恰恰踩进了最典型的认知误区。我最初也花了整整两天时间在各大应用市场、GitHub和小众论坛里翻找所谓的…

2026/6/22 7:51:37阅读更多 →
Godot Engine采用分层架构设计

Godot Engine采用分层架构设计

Godot Engine采用分层架构设计,官方文档提供了从核心组件到底层驱动的整体架构示意图,清晰展示各模块的层级关系与核心职责。一、核心四层架构Godot的引擎主体从底层到上层分为四个核心层级,各层职责明确且依赖关系清晰:‌Core&am…

2026/6/22 9:37:34阅读更多 →
Spring Boot JAR加密实战:使用XJar保护Java应用源码安全

Spring Boot JAR加密实战:使用XJar保护Java应用源码安全

1. 项目概述:当你的Spring Boot JAR包需要“穿盔甲”在Java后端开发,尤其是Spring Boot生态里,打包成一个可执行的Fat JAR进行部署是标准操作。这个JAR包里塞满了你的业务代码、依赖库和配置文件,只要机器上有合适的Java运行时环境…

2026/6/22 9:37:34阅读更多 →
机器学习可解释性方法的不确定性量化与实践

机器学习可解释性方法的不确定性量化与实践

1. 机器学习可解释性方法的不确定性量化与选择 在机器学习模型日益复杂的今天,模型的可解释性(XAI)已成为确保AI系统透明度和可信度的关键技术。作为一名长期从事工业级AI系统开发的工程师,我深刻体会到:没有不确定性量…

2026/6/22 9:37:34阅读更多 →
CyberpunkSaveEditor:赛博朋克2077存档编辑器的完整使用指南

CyberpunkSaveEditor:赛博朋克2077存档编辑器的完整使用指南

CyberpunkSaveEditor:赛博朋克2077存档编辑器的完整使用指南 【免费下载链接】CyberpunkSaveEditor A tool to edit Cyberpunk 2077 sav.dat files 项目地址: https://gitcode.com/gh_mirrors/cy/CyberpunkSaveEditor 想要完全掌控《赛博朋克2077》的游戏体验…

2026/6/22 9:37:34阅读更多 →
F3D:模块化架构驱动的现代3D可视化引擎深度解析

F3D:模块化架构驱动的现代3D可视化引擎深度解析

F3D:模块化架构驱动的现代3D可视化引擎深度解析 【免费下载链接】f3d Fast and minimalist 3D viewer. 项目地址: https://gitcode.com/GitHub_Trending/f3/f3d F3D(发音为/fɛd/)是一款专注于高性能3D数据可视化的开源工具&#xff0…

2026/6/22 9:37:34阅读更多 →
构建抽象话数据集:评估大语言模型对网络亚文化语言的理解边界

构建抽象话数据集:评估大语言模型对网络亚文化语言的理解边界

1. 项目缘起:当AI撞上“抽象话”最近在折腾大语言模型(LLM)的评测时,我总感觉缺了点什么。主流的评测集,像MMLU、GSM8K、HumanEval这些,确实能测出模型的数学、编程、常识推理能力,但总感觉它们…

2026/6/22 9:32:34阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/22 6:01:42阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/22 1:15:34阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/22 5:42:46阅读更多 →
Codex本地AI编码代理与CC Switch协议适配实战

Codex本地AI编码代理与CC Switch协议适配实战

1. Codex不是“另一个VS Code插件”,而是本地AI编码代理的临界点Codex这个名字,现在被太多人误读了。它不是ChatGPT那个早已停更的旧模型代号,也不是某个新出的VS Code扩展图标——它是2024年中后期悄然浮出水面的一类本地化AI编码代理&#…

2026/6/22 0:04:18阅读更多 →
从MSP430到Flexis QE128:8/32位MCU无缝迁移与低功耗设计实战

从MSP430到Flexis QE128:8/32位MCU无缝迁移与低功耗设计实战

1. 项目概述:当8位MCU遇到性能瓶颈,我们如何优雅升级?在嵌入式开发领域,尤其是电池供电的便携式设备、工业传感器节点或智能家居终端中,我们常常面临一个经典的两难选择:是选择功耗极低但性能有限的8位微控…

2026/6/22 0:04:18阅读更多 →
大语言模型空间推理能力提升:TEXT2SPACE数据集与ASCII增强技术解析

大语言模型空间推理能力提升:TEXT2SPACE数据集与ASCII增强技术解析

1. 项目缘起:当大语言模型“看”不懂空间 最近在折腾大语言模型(LLM)的各种应用时,我发现一个挺有意思的现象:你让模型写首诗、写代码、甚至做逻辑推理,它可能都表现得有模有样。但一旦涉及到需要理解“空间…

2026/6/22 0:04:18阅读更多 →