首页
社区
课程
招聘
[原创]逆向已死2:AI直接操作电脑逆向,无差别替代所有真人
发表于: 2天前 325

[原创]逆向已死2:AI直接操作电脑逆向,无差别替代所有真人

2天前
325

环境说明:本文全部操作基于 Windows 10 x64,命令默认在 Windows 原生 PowerShell 中执行;手机端使用 Pixel 2 XL / Android 10。下文的路径、安装步骤与桌面操作均按这一环境记录。

逆向这十多年 都是靠一次次人工手动操作 解码混淆 寻址,拿到 APK,先用 apktool 拆包、jadx 翻代码,从 Manifest 和入口类里找线索;碰到混淆,就追交叉引用、认控制流,给那些看不出意思的类名和函数名一点点补上含义。走到 JNI,打开 IDA、Ghidra,盯着 ARM 汇编寻址,顺着寄存器和内存里的数据追算法。静态分析卡住,再上 Frida 下钩子、用调试器打断点,把参数和返回值抓出来对照。最后还得写 Python 脚本还原逻辑,接上 ADB 和真机,一遍遍输入、运行、看结果。每走一段,都有一套技能要学、一堆窗口要切,大家真的不容易

而今天本文讲的主题是 MCP 已死,GUI 当立 当AI真的可以直接操作电脑逆向,无差别替代所有真人,以往的不可能正在真的走向现实

GUI 给 AI 自动化逆向打开了无限可能,软件摆在桌面上,模型可以直接动手操控鼠标点击键盘 更厉害的是,IDA 里追函数、终端里跑脚本、手机上验结果,几个窗口之间来回折腾的活,可以让同一个 Agent 接着干。碰到报错和弹窗,它还能看着现场继续判断、尝试处理,原来需要人死守屏幕的那些环节,几乎被强大的GUI通杀

自此再也不需要憋屈地用着专用 MCP 打转,以前的MCP时代 有时软件明明有这个功能,服务器没暴露,模型再想干也得等你补接口。好不容易接上,换个工具又得找插件、查版本,逆向还没开始,环境配置先把人折腾掉半条命。分析流程终于跑了,偏偏桌面弹出个确认窗口,接好的分析接口管不到这里,最后还是你伸手点鼠标——好家伙,说好的 AI 给人打工,自己倒成了 AI 的贴身保姆。

而比起MCP的笨拙繁杂,GUI就是冲着全自动化的王位来的,通过 CUA 读取画面、模拟鼠标键盘,模型可以完全模拟真人点击菜单、拖动窗口,字太小就缩放屏幕;进了 IDA,更是全自动输入地址跳转,沿交叉引用寻址,打开反编译结果继续分析。需要执行命令就切终端,需要验证就切手机,输入答案、点击确认,再看程序给出什么结果。你坐在电脑前怎么操作,它就沿着这套方式看、想、动手。完全模拟真人操作,把整段工作里的人工接力一起替下来,这才是 GUI 要拿下的东西。 古法手搓最磨人的那些来回切换,今天终于迎来了AI的接管。

新王来临 我才终于明白"模型是系统的主体,而不只是组件"的最终含义 ———— AI直接操作电脑逆向,无差别替代所有真人
各位先把咖啡端好,下面请欣赏新王第一次作战 以全自动的战果致敬古法逆向的黄昏绝唱。

下文把这次 AI 自动化逆向 的过程完整展开。

先准备账号和环境,然后把桌面操作、分析工具和手机接上:

本次使用已有的可登录账号。若通过购买方式取得账号,先完成登录与恢复方式设置,再进入 Codex。

Windows 原生 PowerShell 下的 Codex CLI 安装与启动步骤

从开始菜单打开 Windows PowerShell,在当前用户的临时目录下载官方安装脚本:

第一行切换下载位置,第二行保存安装脚本,第三行启动安装。这里的 -ExecutionPolicy Bypass 仅作用于本次启动的 PowerShell 进程

安装步骤参考:OpenAI 官方 Windows 部署说明:160K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9k6h3q4J5L8W2)9J5k6h3y4Z5j5i4c8Y4M7s2c8Q4x3X3g2U0L8$3#2Q4x3V1k6V1L8$3y4K6i4K6u0r3k6h3&6@1k6i4u0H3M7X3W2K6k6g2)9J5c8Y4N6A6L8X3c8G2N6%4y4Q4x3X3c8V1k6i4m8D9L8%4W2E0k6h3&6@1。

安装结束后,关闭当前 PowerShell 窗口,再打开一个新窗口,检查命令位置和版本:

如果提示找不到 codex,先检查默认安装位置:

返回 True 时,可以先用完整路径检查版本:

如果完整路径可用而短命令不可用,检查 Windows 的“用户环境变量 → Path”是否包含 %LOCALAPPDATA%\Programs\OpenAI\Codex\bin,补齐后重新打开终端。返回 False 则需要回看安装输出,确认是否安装完成或使用了自定义路径。

在 PowerShell 中执行:

按提示在浏览器中完成 ChatGPT 登录与授权,然后回到终端确认:

首次写作时,本机记录的版本为 codex-cli 0.164.0,登录方式显示 ChatGPT。这个版本号用于说明当时的实验环境。

登录步骤参考:OpenAI 官方身份验证说明:8c2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9k6h3q4J5L8W2)9J5k6h3y4Z5j5i4c8Y4M7s2c8Q4x3X3g2U0L8$3#2Q4x3V1k6V1L8$3y4K6i4K6u0r3j5i4g2@1K9l9`.`.。

为题目和分析文件建立固定目录。下面以用户目录中的 AndroidReverseLab 为例:

进入 Codex 交互界面后,输入下面的任务描述:

这里先完成 Codex 的安装、登录与任务启动,后续再按本文顺序接入 CUA、逆向工具和手机。CLI 的基本使用方式见 OpenAI 官方 Codex CLI 入门:e75K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9k6h3q4J5L8W2)9J5k6h3y4Z5j5i4c8Y4M7s2c8Q4x3X3g2U0L8$3#2Q4x3V1k6V1L8$3y4K6i4K6u0r3j5$3I4A6。

项目地址:

7f2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6r3K9h3&6e0k6h3y4@1k6h3y4Z5i4K6u0V1L8r3q4T1i4K6u0r3k6X3W2F1M7$3g2@1i4K6u0r3

仓库首页主要说明 Linux 环境,Windows 版本位于 r0env2-windows/r0env2。对应安装说明:

613K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6r3K9h3&6e0k6h3y4@1k6h3y4Z5i4K6u0V1L8r3q4T1i4K6u0r3k6X3W2F1M7$3g2@1i4K6u0r3j5X3I4G2j5W2)9J5c8X3#2S2K9h3&6Q4x3V1k6J5x3r3g2F1N6U0u0Q4x3X3c8%4K9h3&6V1L8%4N6K6i4K6u0r3M7U0m8W2L8Y4j5J5i4K6u0r3f1V1g2m8c8p5#2q4i4K6u0W2P5X3S2Q4x3X3c8o6e0W2)9J5k6h3#2V1

下载仓库 ZIP,解压后把整个 r0env2 文件夹放到固定位置,例如 C:\Tools\r0env2。准备 Python 3.10+ 和 VC++ x64 运行库,然后运行:

安装器会准备虚拟环境和浏览器组件。接着填代理端口,先看预览结果:

这里的 18080 要换成代理软件的 HTTP 或混合端口。apply 会改系统设置,要在管理员终端运行。这次补写只检查了现有文件,没有重新执行 apply。

本机已经有 r0env2,放在桌面目录。启动器和 .venv\Scripts\python.exe 都在,r0env.cmd 直接调用这个 Python。

接下来安装 CUA 并测试桌面操作。Java 层使用 jadx;我选择官方 IDA Free 后,又为 ARM 分析补充了 Ghidra。手机通过 QtScrcpy 连接,各工具的下载地址和安装过程见第四节。

原始 APK 在 Pixel 2 XL 上显示 Great

最终结果:原始 Android2.0.apk,Pixel 2 XL / Android 10,输入 flag{sosorryla},显示 Great。

最初发的要求是“帮我安装 IDA 和 jadx,看看能不能用”。题目是后面才给的。

装完 IDA,我先让它试 F5,随后又问 ARM 的 so 能不能用。当前 Free 版做不了,这才转到 Ghidra。Java 版本和手机投屏也是边用边配的。

任务在对话中逐步补充,最初只要求安装 IDA 和 jadx。安装完成后,我继续询问 ARM 支持情况,AI 随后检查当前 IDA Free 的能力,再配置 Ghidra。

切换工具时,已有进程和测试文件继续保留。处理题目的 so 时使用此前通过 ARM32 / ARM64 测试的 Ghidra,jadx 也沿用自带 JRE 的安装。

本次用到的调用关系:

通过 jadx 图形界面查看入口,同时用 CLI 批量导出源码。Ghidra 保留分析工程,另用 headless 脚本导出伪代码。手机端由 CUA 完成点击,特殊字符输入出现偏差后,用 ADB 修正文本。

list_windows 能找到窗口,get_window_state 能读控件或截图,bring_to_front 可以恢复窗口。可点击、键盘输入返回成功后,仍要再看一次界面。尤其是 Java Swing 应用,有些后台消息被发出去了,窗口没有处理,必须切到前台重试。

一次点击返回 screenshot_context_missing,重新获取截图后才继续操作。窗口最小化时先恢复,布局变化后重新读取控件。有些 Swing 界面更新较慢,调用返回后,对话框才出现。

CUA 仓库:

796K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6@1M7Y4W2U0N6h3q4Q4x3V1k6U0N6h3p5`.

当时我提的要求是:

装不用登账号的 cua-driver 即可。

装好本机 driver 后,它开始通过窗口列表、控件树和截图操作桌面。使用过的接口包括 list_windows、get_window_state、bring_to_front、点击、热键、文本输入,以及把一串操作放在一起执行的 run_script。

本机实际装的是 cua-driver 0.37.0,可执行文件在:

写帖时重新执行 --version,仍能返回版本号。后面操作桌面用的就是这套本机组件,没有为了调用它另登 CUA 账号。

浏览器是最先测试的应用。我让它搜索图片,随后检索 FinSectech 的公开资料并整理报告。展示过程又重复过几次,每页加载后稍作停留,再向下滚动,便于观察内容。

本机组件在 %LOCALAPPDATA%\Programs\Cua\cua-driver\bin 下。目录里除了主程序,还有 UIA 相关可执行文件和 SDK DLL。AI 后面通过 Python 调用这个命令行入口,传入操作名与 JSON 参数,再读取返回的窗口信息。

PowerShell 里这样检查:

补跑时,版本仍是 cua-driver 0.37.0。后续调用用进程 ID 和窗口句柄指定目标。

QtScrcpy 的按钮可以用控件名称定位;Swing 窗口读不到完整控件时,就看最新截图,再按位置操作。两种方式在同一台桌面里交替使用,遇到窗口状态变化再重新读。后面 Ghidra 的 JNI 入口截图,也是这样重新打开菜单、输入符号名定位出来的。

QtScrcpy 的主界面能读到按钮名称。AI 当时没有去猜“启动服务”在屏幕上的位置,调用的核心片段是这样:

代码中的 PID 和窗口句柄取自该轮窗口列表。先获取状态,再点击同一 QtScrcpy 窗口中的按钮;程序重启后重新读取这些标识。

控件树里还能读到设备序列号下拉框、设备列表,以及 startServerBtn、stopAllServerBtn 这类控件标识。服务启动后再列一次窗口,新出现的 Phone-... 才是手机画面。后面的输入和点击转到这个窗口,主配置界面仍然留着。

jadx 和 Ghidra 的情况不一样。有些 Swing 对话框没有出现在普通窗口列表里,它又按进程枚举可见窗口,找到打开文件的对话框,再取一张新截图。文件路径由键盘输入,点开以后再看标题是否换成了目标 APK 或工程名。

这期间出现过一个很具体的错误:screenshot_context_missing。当时一次读取没有带截图,紧接着却要求按坐标点击。Driver 拒绝了这个动作,返回信息要求先获取截图。它随后重新读取窗口,才继续点。

第一次向 jadx 发送 Ctrl+O,接口返回消息已投递,截图仍停留在测试类。改用前台输入后出现文件选择器。此前测试工程尚未关闭,先处理“保存项目”提示,再选择 APK 路径。

手机投屏也经历过类似情况。后台点击能让输入框获得焦点,后台文本输入却没进字段。切到前台后文字出现了,后来读控件树才发现括号不对。这几次操作没有一次返回值就结束,后面都跟着读窗口或截图。

IDA Free 下载入口:

902K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Z5k6i4S2Q4x3X3c8J5j5i4W2K6i4K6u0W2j5$3!0E0i4K6u0r3K9h3c8S2i4K6u0V1k6Y4u0W2k6b7`.`.

接下来我让它安装 IDA 和 jadx 1.5.6,顺便试一下。

我起初给的 IDA 名称是 IDA94ProBable_CN。这个名字没找到可核验的来源,它问了版本选择。我选了官方 IDA Free,随后完成 Hex-Rays 账号登录,才继续从官方渠道下载。

最后装好的是 IDA Free 9.4 SP1。下载目录里还留着 ida-free-pc_94_x64win.exe,大小为 431,243,128 字节。

系统已有的 VC++ 运行库版本是 14.51.36247.0,比安装包附带版本新。运行库安装器返回 1638,拒绝降级。安装流程因此返回非零状态。

它继续检查运行库和程序本体,保留了系统较新的运行库。另一个问题是全局文件关联写入权限不足,随后补建当前用户的 .idb、.i64 关联和桌面快捷方式。

安装位置落在当前用户目录:

签名检查最初缺 Sectigo 中间证书。补齐后,Windows 缓存模式的 Authenticode 验证成功。

装完后,我又问:“你看看现在可以用了吗?”

它拿 Windows 自带 whoami.exe 的副本做静态测试,导入 AMD64 PE,等自动分析完成,再按 F5。测试副本没有被执行。

IDA Free 的 AMD64 反编译测试

IDA 安装验证截图。左侧函数列表、下方自动分析输出和中间 C 伪代码,都是当时留下来的。

日志里能看到:

F5 得到了图中的伪代码。当前插件提示支持 x64 云端反编译,需要联网,禁用批量反编译。

程序文件位于 %LOCALAPPDATA%\Programs\IDA-Free-9.4。免费许可证从官方获取后,放在 %APPDATA%\Hex-Rays\IDA Pro 对应位置;分析数据库另存到样本目录。

全局文件关联写入失败后,改在 HKCU\Software\Classes 下建立当前用户的关联。

补跑时还查了运行库注册项:

实际仍显示 v14.51.36247.00、Installed = 1。这与当时“已有较新运行库,安装器拒绝降级”的排查结果一致。

IDA 安装包签名也重新查了一次:

返回 Valid,签名主体为 Hex-Rays。原来的较新运行库继续保留。

我问“现在可以用了吗”时,它没有只报一个版本号。测试文件取的是 Windows 自带 whoami.exe 的副本,另存到测试目录后交给 IDA。

日志先确认文件格式为 AMD64 PE,再装入 metapc 处理器模块。后面完成导入、异常目录和类型信息处理,才出现自动分析结束的提示。这个阶段会花一点时间,刚看到 IDA 窗口时函数列表还没有稳定下来。

F5 之后,图里显示了入口函数的伪代码。样本目录中也出现了 IDA 写出的 .id0、.id1、.nam、.til 等数据库文件。安装、分析数据库和云端反编译分成了几步,日志都留在各自的阶段。

当时安装器的异常也就是这样追的。运行库安装步骤报 1638,它去看系统已经装了什么;全局关联写入失败,则转去处理用户级关联。主程序后来能打开样本,F5 也能工作,这两处安装问题才算处理完。

用户需要动手的地方主要是 Hex-Rays 登录和版本选择。我选官方 Free 以后,AI 才继续下载和安装。它最初拿到的那个 IDA94ProBable_CN 名称,没有被写成“已安装的 IDA Pro 中文版”。

jadx 1.5.6 发布页:

44dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6K9%4W2D9L8%4c8Q4x3V1k6B7j5h3c8^5i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1k6$3x3g2)9J5k6e0g2Q4x3X3f1$3

jadx 用的是 1.5.6 自带 JRE 的 Windows 包:

电脑原本装着 Java 8。jadx 直接用包里的 JRE 25.0.3,建立桌面快捷方式后,把 GUI 切成中文。

命令行包装的核心是:

相对路径从 jadx 自己的目录找 Java,机器上别的软件仍可以使用原来的 Java 8。

验收也做了一次。它创建一个简单的 Java 类,放进字符串返回和整数相加两个方法,再分别看命令行输出和 GUI 反编译结果。

jadx 安装后的测试类反编译

这张图分析的是自建 JadxSmokeTest,后面的 APK 还没有登场。

我接着问:

ARM 的 so 可以吗?

补跑时分别执行三个 Java 的 -version,输出如下:

jadx 的命令行包装直接调用 jre\bin\java.exe,GUI 也从自己的目录启动。

当时用来验收的测试类也很小,源码就是:

反编译后,两个方法都能恢复。命令行和中文 GUI 也分别试过。

下载完成后,压缩包留在 Downloads。jadx 解压到用户的 Programs 目录,反编译输出另放在题目目录中。后面查文件时,可以直接区分原包、自带运行时和 Java 导出结果。

本次几份包的文件名都保留了下来:

AI 下载 QtScrcpy 时用 Python 处理网络请求,最初的下载循环每次读 1MB。后来补跑摘要检查,改用 hashlib.file_digest 逐块读取。Ghidra 的包有五百多 MB,也没有一次把整个压缩包读进内存。

摘要计算的部分很短:

这是按补跑脚本整理的写法,使用本机的 Python 3.12。得到的值记录到 environment-rerun.json,包大小和版本检查结果也在同一份文件里。Ghidra、JDK、QtScrcpy 的摘要重新算过,与安装时留下的官方发布记录一致。

当前这份 IDA Free 不支持本题的 ARM 库,需要另配工具。

我又问装其他版本会不会冲突,随后同意:

ghidra 也行,不冲突就可以安装。

Ghidra 和 JDK 的仓库:

a6aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6z5j5i4c8A6L8$3&6S2L8q4y4W2j5%4g2J5K9i4c8&6b7h3N6W2L8X3y4&6i4K6u0r3k6$3S2A6k6s2u0S2

81aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6S2k6r3!0H3N6r3W2#2L8g2)9J5c8Y4c8W2L8i4g2J5K9h3^5J5y4g2)9J5k6r3u0A6L8X3q4J5K9h3g2K6

它为 Ghidra 单独准备了 JDK,装好后几套运行时是这样放的:

下载目录里保留着两个包:Ghidra 压缩包 569,712,708 字节,JDK 压缩包 141,167,264 字节。安装时两者的 SHA-256 都核对了官方发布记录,完整摘要附在环境记录里。

机器只有 2GB 内存,浏览器和分析工具同时运行时资源较紧张。AI 为 Ghidra 编写独立启动器,将最大 Java 堆设为 512MB,并限制 CPU 并发参数。

启动器结构如下,路径在这里改成了环境变量写法:

Ghidra 从这里指定 JDK,setlocal 把环境变量限制在这次启动中。桌面快捷方式外面又包了一层隐藏控制台的启动入口。

为了确认 ARM 分析能力,它生成了最小 ARM32、ARM64 ELF 共享对象,各导出一个 add_numbers 函数,然后导入 Ghidra,自动分析并导出 C 伪代码。

Ghidra 的 ARM64 测试库与反编译结果

左边是 add、ret,右边恢复成了 return param_1 + param_2;。

两个架构的小样本都通过了。附件里保留了测试库、生成器、验证脚本与反编译结果。它们用于静态分析验收,没有被拿到手机上运行。

项目选择器曾出现异常:

Ghidra 文件选择器曾弹出的异常

快速操作项目选择器时遇到的 Swing Update Manager 异常。

关闭提示后,项目正常打开,已有分析结果保留。

Ghidra 与 JDK 原来的压缩包还在。补跑时重新流式计算 SHA-256,与安装记录中已核对的官方摘要再次比较,二者都一致:

图形界面启动器用 512MB 堆;后来的这次 headless 复跑则指定 384MB,并将分析并发限制为 2。jadx 的重跑先完成,再启动新的 Ghidra 分析项目,减少两套 Java 分析任务一起占内存的压力。

系统的 JAVA_HOME 没有永久改动,Ghidra 只在自己的启动器中选 JDK。

前面的 IDA 测的是 Windows PE。到了 Ghidra,这次特意准备 ELF 共享对象,分别采用 ARM32 和 ARM64,导出函数名都叫 add_numbers。

ARM64 测试图里可以看到加法指令与 ret,反编译结果是两个参数相加。ARM32 的输出也恢复了相同运算。生成这两个文件的代码、测试库本身和导出脚本都在环境附件里。

这一步由 AI 生成样本并执行分析。我没有另外给它一个已知答案的 Android so。等到题目中出现 lib/armeabi-v7a/libNative.so 时,安装过的工具已经有对应架构的测试结果。

复测时,CodeBrowser 中仍打开着 NativeProject。AI 另建 ReplayNative 工程,导入新导出的 so,原窗口保持打开。

实际 headless 参数包括:

-import 指向新导出的库,-postScript 指定分析完成后要跑的 Java 脚本。这一轮使用 384MB 最大堆,jadx 的重跑先结束,再开始 Ghidra,原先打开的 GUI 则继续保留。

导出脚本调用的是 Ghidra 自带反编译器。核心调用如下,完整文件在附件 ExportNative.java:

脚本遍历函数并写出 C 文件。新工程完成后,AI 又把 JNI、Init、First、Second、Third 的输出与首次文件比较,五个结果一致。新日志没有覆盖旧日志,后来整理文章时还能分别找到。

QtScrcpy 4.2.1 发布页:

b9dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6T1j5i4u0J5P5g2)9J5k6s2u0S2L8W2)9J5c8W2q4@1f1$3y4J5j5%4m8&6i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4x3V1k6@1j5h3N6Q4x3V1k6$3y4q4)9J5k6e0u0Q4x3X3f1I4

接着装 QtScrcpy。

使用的是官方 4.2.1 Windows x64 便携包,大小 32,450,642 字节。安装时核对了 SHA-256:

软件自带 ADB、Qt 和视频相关依赖。解压到当前用户的程序目录,建立快捷方式,再把用户配置中的语言从自动改成 zh_CN。自带 ADB 的版本是 1.0.41 / 33.0.2-8557947。

QtScrcpy 刚装好时的界面

最初这里没有手机。程序打开了,但投屏和鼠标控制还没法验。

我在手机上打开 USB 调试,回了一句:“现在开启usb调试了。”

接下来的检查认出了 Pixel 2 XL。设备状态从 unauthorized 变成 device,QtScrcpy 的列表里也出现了手机。点启动服务后,日志显示服务端文件已经推送,设备信息也正确:

电脑端随后出现渲染错误:

此时设备连接和服务启动均已完成,故障位于电脑端渲染。

它接着去读 QtScrcpy 的 main.cpp,找到选择 OpenGL 后端的分支:配置值为 0 时设置 Qt::AA_UseSoftwareOpenGL。于是先停止服务、备份配置,把用户目录下 config.ini 的这一项改掉:

重启软件并启动服务后,手机设置页面正常显示。

另一次启动停在服务端文件推送之后。关闭自动刷新并重新启动服务后恢复连接,这一处没有继续单独定位。

它打开手机设置,通过投屏点击“网络和互联网”,再读一次前台 Activity。页面已经切过去了。

通过投屏点击后进入网络和互联网

设置页面真的切换了,鼠标控制验证通过。

完成手机控制测试后,我提供了题目链接:

要求是用 CUA 操作已经打开的手机、jadx、IDA 等工具,把题解出来。

便携包里有 adb.exe 和 scrcpy-server,也带了 Qt DLL。软件渲染用的 opengl32sw.dll 同样在包内。

包内有默认 config/config.ini,实际修改的是用户目录里的:

相关设置是:

它先备份配置,再停止服务并退出软件。改好文件后重新启动,渲染选项随进程一起生效。

这次补跑一开始,ADB 又看见了设备,但状态为 offline。执行 adb reconnect offline 后,状态恢复到 device,再重启 QtScrcpy 服务,手机画面重新出现。已有的软件渲染配置仍然有效,这一轮没有再去改图形设置。

手机刚出现时状态是 unauthorized。确认调试授权后,设备变成 device,日志随后才打印出 Pixel 2 XL 和 Android 10。

当时检查用的 ADB 是 QtScrcpy 自带版本。命令按下面的方式定位到它,省得终端意外调用另一份 ADB:

服务启动卡住时,它又查看手机进程和 ADB reverse 列表,区分服务端有没有真正起来。等日志出现设备信息和视频编码器名称,电脑端仍然报 shader 错误,排查才转到 OpenGL。

main.cpp 中的分支给出了配置值和 Qt 属性的对应关系。软件渲染对应 Qt::AA_UseSoftwareOpenGL,所以最后落到 UseDesktopOpenGL=0。修改用户配置后重启进程,手机设置页面出来了。窗口里再点“网络和互联网”,前台 Activity 也发生变化。


[招生]科锐逆向工程师培训(2026年11月13日实地,远程教学同时开班, 第57期)

收藏
点赞 ・1
打赏
分享
最新回复 (2)
雪    币: 1221
活跃值: (865)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2 楼
感谢r0ysue大佬指点
2天前
0
雪    币: 98
活跃值: (3366)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3 楼

感谢r0ysue大佬指点
1天前
0
游客
登录 | 注册 方可回帖
返回