Android Frida检测实战:基于模拟器的三重系统级痕迹识别

news2026/5/23 9:03:31
1. 这不是教你怎么用Frida Hook而是教你如何一眼识破它很多人一听到“Frida检测”第一反应是“哦又一个防逆向的花活儿”然后随手搜几篇Hook绕过教程抄两行Process.isDebuggerConnected()就以为万事大吉。我去年在做一款金融类SDK的加固方案时也这么干过——结果上线两周就被某安全团队用Frida自定义so直接绕过所有Java层检测连日志都没打出来。后来复盘才发现我们压根没搞懂Frida在Android系统里到底“动了什么”只盯着“有没有被调试”这个表象却忽略了它真正落地时必然留下的运行时痕迹内存页属性变更、动态库注入路径、JNI函数表篡改、甚至ART虚拟机内部Method结构体的指针偏移……这些都不是靠isDebuggerConnected()能覆盖的。这篇内容就是从一个防御者的真实工作流出发不讲原理空谈不堆砌术语而是用Android Studio自带的模拟器无需真机、无需root、无需额外ADB权限从零搭建一个可验证、可调试、可扩展的Frida检测Demo。它不追求“100%防住所有高级攻击”但能稳稳拦住95%以上的自动化Hook脚本、批量脱壳工具和初级逆向分析。核心关键词就三个Frida检测、Android Studio模拟器、防御者视角。适合正在做App加固、SDK安全、或刚接触移动安全的开发同学——你不需要会写Native代码只要会点Java、能看懂Logcat、知道怎么跑个AVD就能跟着一步步搭出来并且真正理解每一行检测逻辑背后的系统级依据。为什么非得用模拟器因为真机环境变量太多厂商定制ROM、SELinux策略差异、系统服务版本碎片化……而Android Studio模拟器尤其是x86_64 API 30的系统镜像提供了一个干净、可控、可重复的沙箱环境。我们能在同一台Mac/Windows上反复启动、快照、重置把Frida注入前后的内存状态、进程映射、JNI注册行为全部抓下来对比。这种确定性是真机测试永远给不了的。下面要做的不是“加个壳”而是亲手构建一套可观测、可验证、可调试的检测基线——它将成为你后续集成到正式项目里的第一块砖。2. Frida在模拟器里到底干了什么先看清它的“脚印”要检测Frida得先知道它在哪落脚。很多人以为Frida只是个“动态插桩工具”其实它在Android上是一套完整的运行时注入链包含四个不可分割的环节Agent加载、Runtime初始化、JNI Hook接管、以及最终的JS脚本执行。这四个环节每一个都会在系统层面留下明确的、可被程序主动观测的痕迹。我们不用逆向Frida源码只需在模拟器里跑一次标准流程用系统工具把它们全抓出来。2.1 模拟器环境准备选对AVD是第一步我实测下来最稳定、最易复现的组合是Android Studio版本Flamingo | 2022.2.1 Patch 2或更新AVD配置Device: Pixel 4System Image:Android 11 (API Level 30), x86_64, Google APIsRAM: 2048 MB太小会卡住Frida agent加载VM Heap: 256 MBEnable Device Frame: 关闭减少干扰Boot Option: Cold boot确保每次启动状态一致提示千万别用ARM镜像Frida官方预编译的frida-server只提供x86_64和arm64-v8a两个架构而Android Studio模拟器对ARM支持极差adb push后常出现cannot execute binary file: Exec format error。x86_64镜像原生支持且性能更好是模拟器场景下的唯一合理选择。启动AVD后确认它已就绪adb devices # 应输出类似emulator-5554 device adb shell getprop ro.build.version.sdk # 应输出302.2 Frida注入全流程实录四步动作三处痕迹我们用最简方式触发Frida注入全程记录系统行为下载并推送frida-serverv16.3.8适配Android 11# 下载地址见Frida官方GitHub Release页注意选x86_64 adb push frida-server /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server启动frida-server后台守护adb shell /data/local/tmp/frida-server # 注意这里不加-d参数避免进入debug模式影响检测逻辑用frida-cli attach目标进程我们用系统自带的Settings Appfrida -U -f com.android.settings --no-pause # 等待看到[USB::com.android.settings]- 提示符说明注入成功执行一条最简单的JS命令Java.perform(function() { console.log(Frida is alive!); });现在关键来了——在这四步过程中Frida到底在系统里留下了哪些“脚印”我们用三组命令实时抓取观测维度命令Frida注入前典型输出截取Frida注入后显著变化进程打开的文件描述符adb shell ls -l /proc/$(pidof com.android.settings)/fd/ | wc -l~45个fd8~12个fd其中/dev/ashmem/frida-*、/data/local/tmp/frida-server、/system/lib64/libart.so等新fd高频出现内存映射段重点关注rwx权限adb shell cat /proc/$(pidof com.android.settings)/maps | grep rwx通常为0行Android 11默认禁用W^X新增1~2行如7f8a123000-7f8a124000 rwxp 00000000 00:00 0 [anon:frida]这是Frida Runtime分配的可读写执行内存页已加载的动态库adb shell cat /proc/$(pidof com.android.settings)/maps | grep \.so$ | tail -n 5最后几行通常是libandroid_runtime.so,libart.so,libbinder.so末尾新增/data/local/tmp/frida-agent-64.so路径可能略有不同但含frida和.so是铁律这三处变化就是我们后续在Java/Kotlin层实现检测的黄金锚点。它们不是“概率性特征”而是Frida运行时必须存在的系统级事实。比如那个rwxp内存段——ART虚拟机本身禁止代码页可写Frida为了实现JIT Hook必须通过mmap(MAP_ANONYMOUS)申请一块可读写执行的匿名内存这是它绕不过去的底层约束。再比如frida-agent-*.so这个库名它是Frida Agent模块的固定命名规则在frida-core源码的agent/agent.c里硬编码任何版本都逃不掉。2.3 为什么这些痕迹比“调试器检测”更可靠很多开发者还在用Debug.isDebuggerConnected()或BuildConfig.DEBUG这存在严重缺陷isDebuggerConnected()仅在调试器已连接且正在通信时返回true而Frida注入后可以立即断开调试器连接只保留注入的Agent此时该方法返回false但Hook早已生效BuildConfig.DEBUG是编译期常量Release包里恒为false完全无效SELinux状态、/proc/self/status里的TracerPid字段在Frida使用ptrace(PTRACE_ATTACH)时可能被清零尤其在Android 10导致误判。而我们盯住的这三处fd数量突增、rwx内存段、frida-agent.so路径全部发生在Frida Agent已驻留进程空间之后与调试器是否在线无关。它们是Frida功能实现的必要副作用只要它想Hook Java方法就必须完成这些步骤。这就把检测逻辑从“猜行为”升级为“验状态”可靠性提升一个数量级。3. 在Android Studio里落地一个可运行、可调试的检测Demo现在我们把上面观察到的三个黄金锚点转化为Android Studio里一个真实可运行的Demo App。整个工程不依赖任何第三方加固SDK纯原生Java/Kotlin实现所有检测逻辑集中在FridaDetector.java一个类里。你可以把它直接复制进你的项目也可以作为学习样本逐行调试。3.1 工程结构与依赖说明Target SDK: 30适配我们选用的AVDMin SDK: 21保证ART虚拟机特性可用无额外Gradle依赖不引入frida-java-binding不依赖androidx.security保持最小侵入关键文件app/src/main/java/com.example.fridadetect/FridaDetector.java核心检测逻辑app/src/main/java/com.example.fridadetect/MainActivity.java调用检测并展示结果app/src/main/res/layout/activity_main.xml简单UI含“开始检测”按钮和结果TextView注意此Demo设计为主动检测模式即App启动后手动触发而非后台常驻。这是出于两个现实考虑一是降低性能开销全量maps扫描耗时约80~120ms二是便于开发者在开发阶段单步调试每一步检测逻辑。生产环境如需后台检测可将其封装为WorkManager周期任务但首次集成务必从主动模式开始。3.2 核心检测逻辑详解三道防线层层递进FridaDetector.java的主方法checkFrida()返回一个DetectionResult对象包含isDetected布尔值和reason字符串。它按顺序执行以下三道防线第一道防线/proc/self/fd/下frida相关文件描述符扫描private boolean hasFridaFd() { try { File fdDir new File(/proc/self/fd/); if (!fdDir.exists()) return false; String[] fdList fdDir.list(); if (fdList null) return false; for (String fd : fdList) { try { File fdFile new File(fdDir, fd); String link Os.readlink(fdFile.getAbsolutePath()); // 关键判断链接路径含frida且为设备节点或tmp路径 if (link.contains(frida) || link.contains(/dev/ashmem/) || link.contains(/data/local/tmp/)) { Log.d(TAG, Found frida-related fd: fd - link); return true; } } catch (Exception ignored) {} } } catch (Exception e) { Log.w(TAG, Failed to scan fd, e); } return false; }为什么这招有效Frida Agent在初始化时会创建多个Ashmem共享内存区用于JS引擎通信其名称固定以frida-开头见frida-gum源码gum/gumashmem.c。同时它还会open()自己所在的frida-server二进制文件用于版本校验。这些操作都会在/proc/self/fd/下生成新的符号链接。我们不依赖具体fd编号只匹配链接路径中的关键词鲁棒性极强。第二道防线/proc/self/maps中rwxp内存段扫描private boolean hasRwxMemory() { try { BufferedReader reader new BufferedReader( new FileReader(/proc/self/maps)); String line; while ((line reader.readLine()) ! null) { // 匹配格式7f8a123000-7f8a124000 rwxp 00000000 00:00 0 [anon:frida] if (line.contains( rwxp ) (line.contains([anon:) || line.contains([stack))) { // 排除极少数合法rwx如某些Ndk库的stack guard重点看[anon:frida] if (line.contains(frida) || line.contains(gum)) { Log.d(TAG, Found rwx memory with frida: line); return true; } } } reader.close(); } catch (Exception e) { Log.w(TAG, Failed to read maps, e); } return false; }关键细节解释rwxp权限在Android 11的严格W^X策略下几乎只被Frida、Xposed等框架使用。我们不仅检查权限位还结合内存段名称[anon:frida]双重验证避免误伤。实测中正常App包括使用WebView、OpenGL的App在此项检测中100%通过而一旦Frida注入此项几乎必报。第三道防线/proc/self/maps中frida-agent-*.so动态库扫描private boolean hasFridaSo() { try { BufferedReader reader new BufferedReader( new FileReader(/proc/self/maps)); String line; while ((line reader.readLine()) ! null) { // 匹配.so路径且含frida关键词 if (line.endsWith(.so) (line.contains(frida) || line.contains(gum) || line.contains(frida-agent))) { Log.d(TAG, Found frida so in maps: line); return true; } } reader.close(); } catch (Exception e) { Log.w(TAG, Failed to read maps, e); } return false; }这是最直接、最可靠的证据。Frida Agent模块frida-agent-64.so是整个Hook能力的核心载体它必须被dlopen()加载到目标进程地址空间。无论Frida用spawn还是attach模式此so文件都必然出现在maps中。我们甚至不需要解析完整路径只要line.contains(frida) line.endsWith(.so)即可断定。3.3 MainActivity集成与结果可视化在MainActivity.java中我们这样调用public class MainActivity extends AppCompatActivity { private static final String TAG FridaDemo; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnCheck findViewById(R.id.btn_check); TextView tvResult findViewById(R.id.tv_result); btnCheck.setOnClickListener(v - { long start System.currentTimeMillis(); FridaDetector.DetectionResult result FridaDetector.checkFrida(); long cost System.currentTimeMillis() - start; String msg 检测耗时 cost ms\n 检测结果 (result.isDetected ? ⚠️ 发现Frida注入 : ✅ 未发现异常) \n 判定依据 result.reason; tvResult.setText(msg); Log.i(TAG, Detection finished: result); }); } }UI设计意图不隐藏任何信息。用户点击“开始检测”后看到的不仅是“是/否”结论还有精确到毫秒的耗时和具体的判定依据如“found rwx memory: 7f8a123000-7f8a124000 rwxp ...”。这极大方便了开发者在模拟器里反复验证当你手动adb push frida-server并启动后再点检测结果立刻变成“⚠️ 发现Frida注入”且reason字段精准指向哪一行maps记录——这就是“可观测性”的价值。4. 实战调试与避坑指南那些文档里不会写的细节光把Demo跑起来只是第一步。真正的价值在于当它在你的项目里“失效”时你能否快速定位是哪一环出了问题我在给三个不同客户集成此方案时踩过至少七类典型坑。下面把最致命、最高频的四个配上真实日志和解决方案毫无保留分享。4.1 坑一/proc/self/maps读取为空或权限拒绝——SELinux策略拦截现象在部分AVD尤其是Google Play镜像或真机上new FileReader(/proc/self/maps)抛出FileNotFoundException或SecurityException导致所有基于maps的检测直接跳过。根因分析Android 8.0引入的Strict SELinux策略默认禁止非特权App读取/proc/self/maps。虽然我们的App是debug build但某些ROM如Pixel出厂镜像会收紧allow domain proc_self_maps:file { read open getattr };规则。实测验证adb shell runcon u:r:shell:s0 cat /proc/self/maps # 正常输出 adb shell runcon u:r:untrusted_app:s0 cat /proc/self/maps # Permission denied解决方案不硬抗SELinux改用ActivityManager获取进程信息作为降级方案// 在hasRwxMemory()和hasFridaSo()方法开头加入 if (Build.VERSION.SDK_INT Build.VERSION_CODES.O) { try { ActivityManager am (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ListActivityManager.RunningAppProcessInfo processes am.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo process : processes) { if (process.pid android.os.Process.myPid()) { // Android O 可通过此API间接确认进程状态虽不能替代maps扫描 // 但可作为SELinux拦截时的兜底信号若此处异常说明环境受限 Log.d(TAG, Process info via AM: process.processName); break; } } } catch (Exception e) { Log.w(TAG, AM fallback failed, e); } }提示这不是“完美解决”而是优雅降级。当maps不可读时我们至少能记录SELinux blocked /proc/self/maps access到日志提醒开发者切换到更宽松的AVD如Google APIs镜像而非Google Play而不是让检测逻辑静默失败。4.2 坑二Os.readlink()在Android 7.0以下崩溃——API兼容性陷阱现象在API 23Android 6.0模拟器上Os.readlink()抛出UnsatisfiedLinkError因为libcore.io.Linux类在旧版本中未暴露该方法。解决方案回退到/proc/self/fd/目录遍历File.getCanonicalPath()// 替代Os.readlink(fdPath)的兼容写法 private String getFdLinkCompat(String fdPath) { try { File fdFile new File(fdPath); return fdFile.getCanonicalPath(); // 在API 21稳定可用 } catch (Exception e) { return ; } }经验总结Frida检测不是炫技而是工程实践。宁可牺牲一点精度getCanonicalPath()可能无法解析某些特殊fd也要保证基础功能在目标最低SDK上可用。我们实测API 21~33全部覆盖其中API 21~23用兼容路径24用Os.readlink()平滑过渡。4.3 坑三Frida v16.3.8在模拟器上不触发rwx内存分配——Agent加载模式差异现象用最新版Fridav16.3.8attach后hasRwxMemory()始终返回false但hasFridaSo()为true说明Agent已加载但没分配rwx内存。深度排查通过adb shell cat /proc/$(pidof com.android.settings)/maps人工比对发现v16.3.8默认使用GumQuickCompiler其内存分配策略改为mmap(MAP_PRIVATE)而非MAP_ANONYMOUS因此maps中显示为r-xp而非rwxp。应对策略检测逻辑升级为“r-xp frida关键词”双条件// 在hasRwxMemory()中追加 if (line.contains( r-xp ) (line.contains(frida) || line.contains(gum)) line.contains([anon:)) { Log.d(TAG, Found gum r-xp memory: line); return true; // Frida v16.3.8 的新特征 }教训Frida版本迭代会改变底层行为。我们的检测逻辑必须版本感知。建议在生产环境将Frida版本号可通过frida --version获取纳入检测上下文针对v16.0和v15.x维护两套maps匹配规则。4.4 坑四多进程App中检测失效——忘记切换进程上下文现象你的App有remote进程如:pushFrida注入到该进程但主进程的检测始终为false。根本原因/proc/self/永远指向当前执行代码的进程。FridaDetector.checkFrida()在主进程调用自然只扫描主进程的maps和fd对remote进程完全无感。正确做法在Application.onCreate()中为每个进程单独初始化检测public class MyApplication extends Application { Override public void onCreate() { super.onCreate(); // 获取当前进程名 ActivityManager manager (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ListActivityManager.RunningAppProcessInfo processes manager.getRunningAppProcesses(); String myProcessName ; for (ActivityManager.RunningAppProcessInfo process : processes) { if (process.pid android.os.Process.myPid()) { myProcessName process.processName; break; } } // 根据进程名决定是否启用检测 if (myProcessName.equals(getPackageName()) || myProcessName.equals(getPackageName() :push)) { FridaDetector.startAutoCheck(this); // 启动定时检测 } } }关键点不要试图“跨进程检测”。每个进程都是独立的内存空间必须在每个目标进程中独立执行检测逻辑。这是Android系统的基本隔离原则绕不过去。5. 从Demo到生产如何把它变成你项目里的“安全水位线”这个Demo的价值不在于它多酷炫而在于它提供了一条清晰、可测量、可演进的安全水位线。我把它部署到客户项目中的实际路径分为三个阶段每个阶段都有明确的交付物和验收标准。5.1 阶段一建立基线1天目标在开发环境Android Studio模拟器中100%复现Frida注入与检测响应。交付物一份《AVD配置清单》含镜像下载链接、启动参数截图一份《Frida注入验证脚本》bash adb命令集合一键复现一份《检测日志样例》含注入前/后对比标注关键字段验收标准任意新同事按清单操作15分钟内完成从AVD启动到看到“⚠️ 发现Frida注入”结果。5.2 阶段二集成加固3天目标将FridaDetector无缝嵌入现有App不影响主线功能检测耗时控制在150ms内。关键改造性能优化将三道防线改为异步AsyncTask或Kotlin协程UI线程不阻塞混淆适配在proguard-rules.pro中添加-keep class com.example.fridadetect.** { *; } -keep class android.system.Os { *; }日志分级DEBUG级别输出详细traceRELEASE级别只上报isDetected和cost验收标准在Release包中checkFrida()平均耗时≤120ms实测小米12真机Android 12ANR率0%。5.3 阶段三构建响应闭环持续这才是体现专业性的分水岭。检测出来只是开始如何响应才是关键轻量响应推荐检测到Frida后自动降级关键功能。例如金融App中isDetectedtrue时禁用“一键转账”按钮提示“检测到不安全环境请在正规渠道使用”中量响应触发AlarmManager发送一次加密心跳到风控后台携带设备指纹、检测时间、reason摘要非原始maps内容防泄露重量响应慎用调用android.os.Process.killProcess(android.os.Process.myPid())自杀。这很激进但对高敏感SDK如生物识别模块是合理选择——宁可服务中断也不让Hook得逞。我的个人经验是永远优先选择“功能降级”而非“进程自杀”。前者用户体验可接受后者极易被反调试工具识别为“加固特征”反而成为攻击入口。真正的防御高手不是让App变得“不可破解”而是让破解后的收益远低于成本。最后分享一个小技巧把这个Demo的检测结果和你的Crash监控如Firebase Crashlytics打通。在FridaDetector的onDetected()回调里手动记录一个非致命事件FirebaseCrashlytics.getInstance().log(FRIDA_DETECTED: reason); FirebaseCrashlytics.getInstance().recordException(new Exception(Frida detected));这样你就能在Crashlytics后台用is:non-fatal AND message:FRIDA_DETECTED精准筛选出所有被检测到的设备形成真实的攻击热力图——哪里被扫得最多哪个Frida版本最活跃这些数据比任何理论模型都更有说服力。安全不是玄学它是可测量、可追踪、可优化的工程实践。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…