从零构建APK到Frida动态Hook:Android应用运行时篡改实战指南
1. 项目概述为什么我们要亲手构建APK并Hook它在移动安全研究、应用逆向分析甚至是自动化测试领域Frida 早已不是个陌生的名字。它就像一把瑞士军刀能让我们在应用运行时“为所欲为”——查看、修改函数逻辑甚至凭空注入代码。但很多教程都停留在“如何Hook一个现成的App”上这就像只教你怎么开别人家的锁却不告诉你锁的内部结构。一旦遇到加固、混淆或者复杂的业务逻辑新手往往会一头雾水不知道从何下手。所以我决定换一个思路带大家走一条更扎实的路从零开始亲手构建一个目标APK然后亲手用Frida去Hook它实现动态篡改逻辑。这个过程的魅力在于你既是“造物主”也是“破解者”。你清楚地知道每一行代码在哪里、每一个方法叫什么、参数是什么然后你再亲自去拦截和修改它。这种“自产自销”的实战能让你透彻理解Hook技术的每一个环节从源码到字节码从静态分析到动态注入建立起完整的知识闭环。无论是为了深入理解Android机制还是为后续分析第三方复杂应用打下坚实基础这都是一次不可多得的深度练习。2. 环境搭建与目标APK构建工欲善其事必先利其器。我们的第一步是准备好所有工具并创建一个用于“实验”的目标应用。2.1 核心工具链准备你需要准备以下环境我强烈建议在实体机或性能较好的模拟器如Android Studio自带的AVD上进行某些轻量模拟器可能对Frida支持不佳。Android Studio这是我们的主要开发环境用于编写和构建目标APK。从官网下载并安装最新稳定版即可。安装时注意勾选Android SDK和相应的平台工具。Java Development Kit (JDK)Android Studio通常会捆绑或提示安装确保版本为JDK 11或17根据你的Gradle插件版本兼容性选择。Python 3.xFrida的客户端脚本主要使用Python编写。确保已安装并将pip添加到系统环境变量。Frida这是我们的主角。安装分为两部分客户端 (Client)在你的电脑上安装。打开命令行执行pip install frida-tools。这会同时安装frida和frida-tools包含有用的命令行工具如frida-ps。服务端 (Server)在你的Android设备真机或模拟器上运行。首先通过adb shell getprop ro.product.cpu.abi查看设备架构通常是arm64-v8a或x86_64。然后去Frida的GitHub Releases页面下载对应架构的frida-server-xx.x.x-android-xx.xz文件。ADB (Android Debug Bridge)通常包含在Android SDK的platform-tools目录下。确保adb命令可以在终端中直接调用。注意下载Frida-server时版本号尽量与frida-tools的版本保持一致或接近以避免潜在的兼容性问题。使用frida --version查看客户端版本。2.2 创建并理解我们的“实验靶场”APK我们将创建一个极其简单但功能点清晰的Android应用它包含我们后续要Hook的所有逻辑。新建项目打开Android Studio选择“Empty Activity”模板语言选择Java为了更直观地展示Hook过程Kotlin原理相同。项目名称为HookDemo包名可设为com.example.hookdemo。设计核心逻辑我们修改MainActivity.java添加一些“靶子”方法。package com.example.hookdemo; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final String TAG HookDemo; // 靶子方法1一个简单的加法函数 public int add(int a, int b) { int result a b; Log.d(TAG, “add: “ a “ “ b “ “ result); return result; } // 靶子方法2一个验证登录的函数 public boolean verifyLogin(String username, String password) { Log.d(TAG, “verifyLogin called with: “ username “/“ password); // 简单的硬编码验证 boolean isValid “admin“.equals(username) “123456“.equals(password); Toast.makeText(this, “Login “ (isValid ? “Success“ : “Failed“), Toast.LENGTH_SHORT).show(); return isValid; } // 靶子方法3一个静态方法 public static String getSecret() { return “ThisIsASecretString“; } Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 调用一下我们的方法方便观察 int sum add(5, 3); boolean loginResult verifyLogin(“user“, “pass“); String secret getSecret(); Log.d(TAG, “onCreate: Sum“ sum “, Login“ loginResult “, Secret“ secret); } }构建APK点击Android Studio工具栏的“Build” - “Build Bundle(s) / APK(s)” - “Build APK(s)”。构建完成后将生成的app-debug.apk文件安装到你的测试设备上。使用命令adb install path/to/your/app-debug.apk在设备上找到并打开HookDemo应用观察Logcat输出确认应用正常运行并看到了我们预设的日志。这个APK就是我们的“靶场”。我们知道add方法在MainActivity类里它接收两个int参数返回它们的和。我们知道verifyLogin的校验逻辑是写死的。我们的目标就是在不修改这个APK源码、不重新编译的情况下用Frida改变这些行为。3. Frida基础与设备端部署在开始Hook之前我们必须让Frida在设备端“跑起来”。3.1 部署Frida-Server到Android设备假设你下载的frida-server文件是frida-server-16.1.11-android-arm64.xz。解压并推送首先解压.xz文件得到二进制文件frida-server-16.1.11-android-arm64。# 将文件推送到设备的可执行目录/data/local/tmp 通常具有执行权限 adb push frida-server-16.1.11-android-arm64 /data/local/tmp/赋予执行权限并运行adb shell # 进入目录 cd /data/local/tmp # 赋予可执行权限 chmod 755 frida-server-16.1.11-android-arm64 # 以后台方式运行frida-server注意这里的文件名要和你推送的一致 ./frida-server-16.1.11-android-arm64 符号让其在后台运行。你可以使用ps | grep frida来检查进程是否在运行。端口转发重要Frida-server默认监听TCP端口27042。我们需要通过ADB将这个端口转发到本地以便电脑上的Frida客户端能够连接。# 退出设备的shell如果还在的话在电脑的终端执行 adb forward tcp:27042 tcp:270423.2 验证连接与基础命令现在从你的电脑终端尝试以下命令验证环境是否通畅# 列出设备上运行的所有进程 frida-ps -U # 列出设备上运行的所有Android应用包名格式 frida-ps -Ua如果能看到一长串进程列表恭喜你Frida环境已经搭建成功。-U参数代表连接到USB设备。4. Hook实战从定位到动态篡改现在进入最核心的部分。我们将编写Python脚本利用Frida来Hook我们自己编写的APK。4.1 编写第一个Hook脚本拦截并修改加法结果创建一个Python文件例如hook_add.py。import frida import sys # 定义我们的JavaScript Hook代码 jscode “““ Java.perform(function () { console.log(“[] Hook脚本已加载“); // 定位我们的目标类 var MainActivity Java.use(‘com.example.hookdemo.MainActivity’); // Hook ‘add’ 实例方法 MainActivity.add.implementation function (a, b) { console.log(“[] Hook到 add 方法被调用“); console.log(“ 原始参数: a“ a “, b“ b); // 我们可以篡改参数 var newA a * 2; // 例如把第一个参数乘以2 var newB b 10; // 把第二个参数加10 console.log(“ 篡改后参数: newA“ newA “, newB“ newB); // 调用原始方法但传入篡改后的参数 var originalResult this.add(newA, newB); // 注意这里调用原始实现 console.log(“ 原始方法结果基于篡改参数: “ originalResult); // 我们甚至可以篡改返回值 var finalResult originalResult - 100; console.log(“ 最终返回结果: “ finalResult); return finalResult; }; console.log(“[] add 方法Hook设置完成“); }); “““ def on_message(message, data): if message[‘type’] ‘send’: print(“[APP LOG]: “ message[‘payload’]) else: print(message) # 连接到设备 device frida.get_usb_device() print(“[] 已连接到设备: “ str(device)) # 附加到目标进程我们的HookDemo应用 # 首先需要启动应用或者确保它正在运行。这里我们通过包名来附加。 try: # 方式一附加到已存在的进程 pid device.spawn([“com.example.hookdemo“]) # spawn会启动应用但暂停它 session device.attach(pid) device.resume(pid) # 恢复应用执行 print(“[] 已启动并附加到进程 PID: “ str(pid)) except Exception as e: # 方式二如果应用已在运行直接附加 print(“[!] 尝试附加到运行中的进程...“) session device.attach(“com.example.hookdemo“) # 创建并加载脚本 script session.create_script(jscode) script.on(‘message‘, on_message) print(“[] 正在加载Hook脚本...“) script.load() # 保持脚本运行等待Hook事件触发 print(“[] Hook脚本加载成功请操作App触发add方法或等待onCreate调用。“) print(“[] 按 CtrlC 停止脚本。“) sys.stdin.read()脚本解析与核心技巧Java.perform这是Frida在Android上执行Java层Hook的入口函数所有相关操作必须包裹在其中以确保在正确的线程上下文中执行。Java.use(‘完整类名’)用于获取一个JavaScript wrapper来代表目标Java类。这是定位类的关键。.implementation这是Frida最强大的特性之一。通过重写一个方法的implementation属性我们就替换了它的原始实现。在重写的函数里this指向当前对象实例。this.add(...)在Hook函数内部通过this.方法名(...)可以调用方法的原始实现。这是实现“先执行原逻辑再修改结果”或“修改参数后执行原逻辑”的基础。参数与返回值你可以任意读取、修改方法的参数和返回值。这是动态篡改逻辑的核心。运行与观察确保设备上的HookDemo应用已经关闭。在终端运行python hook_add.py。脚本会启动应用并附加。此时在设备上打开HookDemo应用。观察Python脚本控制台的输出。你会看到add方法被onCreate调用时我们的Hook脚本成功拦截打印了原始参数(5, 3)篡改后参数(10, 13)原始结果23以及最终返回的篡改结果-77。同时观察Android Studio的Logcat你会发现应用自己打印的日志add: 5 3 -77。看返回值已经被我们篡改了但应用对此一无所知它以为add(5,3)真的返回了-77。4.2 深入Hook篡改登录验证逻辑接下来我们HookverifyLogin方法实现一个“万能密码”。创建新脚本hook_login.pyJavaScript部分修改如下Java.perform(function () { console.log(“[] 开始Hook登录验证...“); var MainActivity Java.use(‘com.example.hookdemo.MainActivity’); MainActivity.verifyLogin.implementation function (username, password) { console.log(“[] 登录验证被调用“); console.log(“ 用户名: “ username); console.log(“ 密码: “ password); // 动态篡改逻辑无论输入什么只要密码是“frida“就算成功 var isMagicPassword “frida“.equals(password); if (isMagicPassword) { console.log(“[!] 检测到万能密码 ‘frida‘强制验证通过“); // 直接返回true完全绕过原始验证逻辑 return true; } // 如果不是万能密码则执行原始验证逻辑 console.log(“ 执行原始验证逻辑...“); var originalResult this.verifyLogin(username, password); console.log(“ 原始验证结果: “ originalResult); return originalResult; }; console.log(“[] verifyLogin 方法Hook设置完成“); });技巧与思考在这个例子中我们没有调用原始方法就返回了true这意味着原始的业务逻辑检查admin/123456被完全短路Bypass了。这在安全测试中常用于绕过客户端校验。你可以尝试修改脚本在调用原始方法this.verifyLogin时将参数篡改为正确的admin和123456这样无论用户输入什么最终都会以管理员身份登录。这演示了另一种攻击向量。4.3 挑战Hook静态方法Hook静态方法略有不同因为this在静态上下文中没有意义。我们修改hook_static.py的JS代码Java.perform(function () { console.log(“[] 开始Hook静态方法...“); var MainActivity Java.use(‘com.example.hookdemo.MainActivity’); // Hook静态方法 MainActivity.getSecret.implementation function () { // 注意这里没有参数 console.log(“[] 静态方法 getSecret 被调用“); // 调用原始静态方法 var originalSecret MainActivity.getSecret(); // 注意调用方式变了用类名而不是this console.log(“ 原始秘密: “ originalSecret); // 篡改返回值 var fakeSecret “HackedByFrida!“; console.log(“ 返回假秘密: “ fakeSecret); return fakeSecret; }; console.log(“[] getSecret 静态方法Hook设置完成“); });关键区别在Hook静态方法的实现里调用原始方法使用的是类名.方法名()即MainActivity.getSecret()而不是this.getSecret()。因为this指向实例对象而静态方法属于类本身。运行这个脚本再次打开应用你会发现Logcat中打印的Secret变成了我们返回的HackedByFrida!。5. 高级技巧与实战问题排查掌握了基本Hook后我们面对真实场景会更复杂。以下是一些进阶技巧和常见问题的解决方案。5.1 枚举与Hook重载方法如果一个类中有多个同名但参数不同的方法重载我们需要精确指定。假设我们的MainActivity有另一个add方法接收double类型。public double add(double a, double b) { return a b; }在Frida中我们可以使用.overload(‘参数类型‘)来指定var MainActivity Java.use(‘com.example.hookdemo.MainActivity’); // Hook int add(int, int) MainActivity.add.overload(‘int‘, ‘int‘).implementation function(a, b) { // ... hook logic for int version }; // Hook double add(double, double) MainActivity.add.overload(‘double‘, ‘double‘).implementation function(a, b) { // ... hook logic for double version };参数类型使用JNI签名简写如int,double,java.lang.String,[B(byte数组),[Ljava.lang.String;(String数组)等。5.2 主动调用Java方法Frida不仅能拦截调用还能主动发起调用。这在需要触发特定逻辑或查询对象状态时非常有用。Java.perform(function () { // 使用Java.choose在堆上查找已存在的对象实例 Java.choose(‘com.example.hookdemo.MainActivity‘, { “onMatch“: function(instance) { console.log(“[] 找到MainActivity实例: “ instance); // 主动调用实例方法 var result instance.add(100, 200); console.log(“[] 主动调用add(100,200)结果: “ result); }, “onComplete“: function() { console.log(“[] 实例搜索完成。“); } }); // 主动调用静态方法 var secret Java.use(‘com.example.hookdemo.MainActivity‘).getSecret(); console.log(“[] 主动调用静态方法getSecret(): “ secret); });5.3 常见问题排查实录在实际操作中你几乎一定会遇到下面这些问题。问题1Java.perform错误或类找不到现象Error: java.lang.ClassNotFoundException: com.example.hookdemo.MainActivity。排查包名/类名拼写错误这是最常见的原因。使用frida-ps -Ua确认应用包名使用反编译工具如JADX或查看R.java确认完整类名。类加载器问题有些类由自定义ClassLoader加载。可以尝试枚举所有ClassLoader来查找类Java.enumerateClassLoaders({ onMatch: function(loader){ try { if (loader.findClass(“com.example.hookdemo.MainActivity“)) { console.log(“[] 找到目标ClassLoader: “ loader); Java.classFactory.loader loader; // 切换ClassLoader } } catch(e) {} }, onComplete: function(){} });应用未启动或进程错误确保脚本附加的是正确的进程。对于多进程应用UI主进程的包名通常就是应用包名。问题2Hook后应用崩溃或行为异常现象Hook后应用闪退或功能不正常。排查参数/返回值类型不匹配在Hook函数中返回的类型必须与原方法声明的类型完全一致。int不能返回String。未调用原始方法如果你替换了implementation但某些关键逻辑如初始化、状态设置在原始方法中不调用它可能导致后续崩溃。除非你明确想阻断该逻辑。递归调用在Hook函数内部如果你又调用了同一个被Hook的方法且没有条件限制会导致无限递归和栈溢出。确保你的调用逻辑有终止条件或使用一个标志位来避免。var isHooked false; MainActivity.someMethod.implementation function(arg) { if (isHooked) { return this.someMethod(arg); // 调用原始实现 } isHooked true; // ... 你的hook逻辑 var result this.someMethod(arg); // 这里会再次进入本函数但被标志位拦截 isHooked false; return result; };问题3Frida-server连接失败或进程列表为空现象frida-ps -U无输出或报错。排查ADB连接确保adb devices能看到你的设备。端口转发确认执行了adb forward tcp:27042 tcp:27042。Frida-server未运行重新进入adb shell检查/data/local/tmp/下的进程是否存在并用ps | grep frida确认。如果没有重新执行运行命令。权限问题确保是以root权限运行frida-server在已root的设备或模拟器上。非root环境需要一些额外配置且能力受限。版本不匹配确保电脑端的frida和frida-tools版本与设备端的frida-server版本大致兼容。问题4如何Hook Native (SO库) 函数Frida同样强大。使用Interceptor.attach来Hook Native函数。// 假设有一个libnative.so里面导出了函数int add(int a, int b) var nativeAdd Module.findExportByName(“libnative.so“, “_Z3addii“); // 需要函数修饰名 Interceptor.attach(nativeAdd, { onEnter: function(args) { console.log(“[] Native add called.“); console.log(“ arg[0] (a): “ args[0].toInt32()); console.log(“ arg[1] (b): “ args[1].toInt32()); }, onLeave: function(retval) { console.log(“ returning: “ retval.toInt32()); // 篡改返回值 retval.replace(999); } });获取准确的函数符号名是Native Hook的关键可以使用objdump -T或nm工具查看SO库。6. 项目总结与扩展思路通过这个从构建APK到实现动态Hook的完整流程我们亲手验证了Frida的核心能力在运行时对已知和未知的代码逻辑进行观察、拦截与篡改。我们从一个清晰的“靶场”开始避免了逆向分析中“黑盒”的迷茫专注于掌握Hook技术本身。我个人在实际操作中的体会是理解“上下文”至关重要。无论是Java层的this与类名调用区别还是Native层的参数传递约定亦或是多ClassLoader环境本质上都是代码执行环境的问题。Frida给了我们上帝视角但我们必须理解这个世界的运行规则才能有效地施加影响。这个项目可以轻松地扩展复杂参数处理尝试Hook接收或返回复杂对象如List、自定义类的方法学习如何使用Frida的API去构造和解析这些对象。批量Hook与RPC编写更复杂的脚本一次性Hook多个类或方法。甚至利用Frida的rpc.exports功能将Hook到的函数暴露给Python端调用实现双向通信。对抗简单反调试一些应用会检测Frida。你可以尝试在自定义的APK中加入简单的反Frida代码如检测端口27042、检测frida-server进程名然后编写Frida脚本来绕过这些检测这是一场有趣的攻防练习。结合自动化将你的Frida脚本与UI自动化工具如Appium结合模拟用户操作触发特定功能同时进行动态数据篡改实现更复杂的自动化测试场景。记住技术本身无分对错。在合法授权的范围内用这些技能去加固你自己的应用、进行安全评估或自动化测试才是它最大的价值所在。希望这篇长文能成为你探索Android动态分析世界的一块坚实跳板。

相关新闻

C++视频会议系统开发实战:从Socket通信到音视频编解码全流程解析

C++视频会议系统开发实战:从Socket通信到音视频编解码全流程解析

1. 项目概述:从零构建一个C视频会议系统最近在整理硬盘,翻出来一个几年前自己用C写的视频会议系统Demo源码。当时做这个项目,主要是想深入理解一下实时音视频传输和网络编程的底层逻辑,市面上成熟的方案很多,但“黑盒”…

2026/10/13 4:48:16 阅读更多 →
Linux C++日志库log4cpp编译安装与实战配置指南

Linux C++日志库log4cpp编译安装与实战配置指南

1. 项目概述:为什么我们需要一个专业的C日志库? 在Linux下用C做项目,尤其是服务器后台或者嵌入式系统,日志功能几乎是刚需。你肯定遇到过这种场景:程序在测试环境跑得好好的,一上线就出各种稀奇古怪的问题&…

2026/10/13 4:48:17 阅读更多 →
C++实战:深入Windows打印子系统,彻底卸载打印机驱动

C++实战:深入Windows打印子系统,彻底卸载打印机驱动

1. 项目概述与核心价值 打印机驱动卸载,听起来是个简单粗暴的操作,无非就是“控制面板-程序和功能-卸载”或者用第三方工具一键清理。但如果你在开发打印管理软件、企业IT运维工具,或者需要批量部署、静默卸载驱动时,就会发现事情…

2026/9/27 15:47:02 阅读更多 →

最新新闻

环形缓冲区空/满判断:三种方案与面试手写要点

环形缓冲区空/满判断:三种方案与面试手写要点

环形缓冲区的实现和空/满判断,是我在技术面试里最常问的基础题,没有之一。它的代码量不超过五十行,看起来就是一个数组加两个下标,可每次让候选人在白板上写下来,十分钟内能把边界情况全部写对的人真的不多。尤其是“这…

2026/10/13 4:48:14 阅读更多 →
环形缓冲区核心实现:空满判断、性能优化与典型应用

环形缓冲区核心实现:空满判断、性能优化与典型应用

凡是亲手写过生产者-消费者代码的开发者,几乎都会和环形缓冲区打一次照面。这玩意儿听起来基础,但在音频采集、网络收包、日志异步落盘这些每天都在跑的路径上,它都扮演着核心角色。面试时,环形缓冲区(循环队列&#x…

2026/10/13 4:48:14 阅读更多 →
测试工程师转脑机接口调试:认证路径与实操指南

测试工程师转脑机接口调试:认证路径与实操指南

这两年,我身边聊脑机接口(BCI)的测试工程师明显多了。问得最多的一句话是:搞了五六年功能测试、接口测试,突然想去碰脑机接口这种听起来像科幻片的东西,还考什么调试认证,到底靠不靠谱&#xff…

2026/10/13 4:48:14 阅读更多 →
TensorFlow 2.x自定义Layer四大生命周期详解

TensorFlow 2.x自定义Layer四大生命周期详解

1. 为什么自定义Layer不是“高级技巧”,而是TensorFlow 2.x的日常刚需刚接触TensorFlow 2.x时,我跟很多开发者一样,以为tf.keras.layers.Dense、Conv2D这些内置层就是全部——写模型就是搭积木,调参就是改数字。直到在某次图像增强…

2026/10/13 4:48:14 阅读更多 →
计算机系统思维导图:数据通路与控制通路双主线解析

计算机系统思维导图:数据通路与控制通路双主线解析

1. 项目概述:一张图理清计算机系统全貌,为什么这张思维导图能解决90%的组成原理困惑?“计算机系统概述”这门课,很多人学完还是云里雾里——CPU、内存、I/O、总线、指令周期、冯诺依曼结构……名词堆了一大堆,但一问“…

2026/10/13 4:48:14 阅读更多 →
深入解析keepalived中vrrp_state_master_rx状态裁决机制

深入解析keepalived中vrrp_state_master_rx状态裁决机制

1. 为什么一个VRRP状态机函数值得单独深挖?在某高校网络实验室搭建高可用网关集群时,我第一次遇到keepalived的“脑裂”现象:两台设备同时宣称自己是Master,下游流量被随机打散,业务接口超时率瞬间飙升到70%。排查日志…

2026/10/13 4:47:13 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →