[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-75452":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},75452,"Scene-Port-Hider-by-eBPF","Andrea-lyz\u002FScene-Port-Hider-by-eBPF","Andrea-lyz","隐藏Scene运行时的端口",null,"C",271,818,5,1,0,3,13,156,9,68.24,false,"main",true,[],"2026-06-12 04:01:18","# Scene Port Hider by eBPF\n\n这是一个 KernelSU 模块，用来隐藏 Scene 常用 TCP 端口 `8788` 和 `8765` 的端口探测。\n\n模块使用 eBPF 在内核侧做端口行为隐藏，当前覆盖：\n\n- `connect()` 型探测：使用 `cgroup\u002Fconnect4` 和 `cgroup\u002Fconnect6` 将非白名单应用对目标端口的本机连接重定向到无服务端口。\n- `bind()` 型探测：使用 `cgroup\u002Fbind4` 和 `cgroup\u002Fbind6` 将非白名单应用对目标端口的本机绑定临时改为随机端口。\n- `bind + getsockname()` 一致性探测：用 kprobe\u002Fkretprobe 按 `tgid + fd` 记录原始端口，多次 `getsockname(fd)` 都回填一致结果，并在 `close(fd)` 时清理状态。\n\n模块不使用 `iptables` \u002F `ip6tables`，也不再依赖 `service.d` 脚本。\n\n默认目标应用包名是 Scene：\n\n```sh\ncom.omarea.vtools\n```\n\n## 更新内容\n\n### v2.0.1\n\n- 修复隐藏端口匹配过宽的问题。现在只按 socket API 使用的网络字节序写入目标端口，避免 `8788` 误伤字节翻转后的 `21538`、`8765` 误伤 `15650`。\n- 降低无关应用本地服务被误判为检测器的概率。\n\n### v2.0\n\n- 改为纯 eBPF\u002Fcgroup socket hook 方案，不再写入 `iptables` \u002F `ip6tables` 规则，也不再依赖 `service.d` 脚本。\n- 新增 `cgroup\u002Fconnect4`、`cgroup\u002Fconnect6` 处理连接型探测，将非白名单应用对隐藏端口的本机连接重定向到无服务端口。\n- 新增 `cgroup\u002Fbind4`、`cgroup\u002Fbind6` 处理 bind 型探测，将非白名单应用对隐藏端口的本机绑定临时改为随机端口。\n- 新增 `bind + getsockname()` 一致性处理，避免检测器通过 `bind()` 后读取实际端口发现改写痕迹。\n- 新增 `close()` 清理逻辑，按 `tgid + fd` 清除临时记录，降低长时间运行后的状态残留风险。\n- 优化 Scene UID 白名单解析，等待包管理器或运行进程提供真实 UID，避免开机早期误判 UID 导致 Scene 自身无法连接 daemon。\n- 新增安装时 BTF 指纹校验，模块包内 `btf\u002Fvmlinux.btf` 必须和当前设备 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux` 一致，降低刷错设备包的风险。\n\n## Root 方案兼容性\n\n模块采用通用 Magisk 模块结构，理论兼容：\n\n- KernelSU\n- Magisk\n- APatch \u002F APM\n\n当前主要在 KernelSU 环境测试通过。\n\nMagisk 和 APatch 用户需要自行确认设备内核满足 eBPF、BTF、cgroup socket hook、kprobe\u002Fkretprobe 等要求。这个模块能否正常工作，主要取决于内核能力，而不是 root 管理器本身。\n\n## 重要说明\n\n这个模块和手机内核强相关。不同手机、不同系统版本、不同内核构建出来的模块不一定通用。\n\n推荐每个用户都用自己手机的 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux` 自助构建一次。\n\n不要直接拿别人设备构建出来的包乱刷。\n\n新版本模块会在安装时检查内核 BTF 指纹。如果模块包里的指纹和当前手机 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux` 不一致，安装会被拒绝，避免刷错设备。\n\n## 设备和内核要求\n\n这个模块不是所有 root 设备都能用。建议满足以下条件再尝试：\n\n- 设备是 arm64 \u002F arm64-v8a。\n- 已安装 KernelSU，并且 ADB 可以获取 root 授权。\n- 当前内核支持 eBPF、BPF map 和 cgroup socket hook。\n- 当前内核存在 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux`。\n- `\u002Fsys\u002Ffs\u002Fcgroup` 可用，并允许 root 使用 legacy `BPF_PROG_ATTACH` 挂载 `connect4\u002Fconnect6` 和 `bind4\u002Fbind6` 程序。\n- 当前内核允许挂载 `bind`、`getsockname`、`close` 相关 kprobe\u002Fkretprobe。\n\n普通用户可以先执行：\n\n```sh\nsu\nls -lh \u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux\nexit\n```\n\n如果提示文件不存在，当前公开自助构建方案基本不支持这台设备。\n\n如果想进一步检查：\n\n```sh\nsu\nuname -a\ngetprop ro.product.cpu.abi\nmount | grep \" \u002Fsys\u002Ffs\u002Fcgroup \"\ncat \u002Fsys\u002Ffs\u002Fcgroup\u002Fcgroup.controllers 2>\u002Fdev\u002Fnull\ncat \u002Fproc\u002Fkallsyms | grep -E \"(__sys_bind|__arm64_sys_bind|__sys_getsockname|__arm64_sys_getsockname|__arm64_sys_close)\" | head\nexit\n```\n\n一般建议 Android 12 以后、内核 5.4 以后、有 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux` 的 arm64 设备再尝试。这个版本线不是绝对要求，因为有些厂商会回移植 eBPF\u002FBTF，也有些新内核会裁剪相关能力。\n\n## 普通用户自助构建\n\n这条路线最简单：不需要自己安装 Android Studio、NDK、bpftool 或 libbpf，只需要 Fork 仓库，然后让 GitHub Actions 自动构建。\n\n### 1. Fork 仓库\n\n打开本仓库，点右上角 `Fork`，创建到自己的 GitHub 账号下面。\n\n进入自己 Fork 后的仓库，点 `Actions`。\n\n如果 GitHub 提示启用 Actions，就点启用。\n\n### 2. 从自己的手机导出 BTF\n\n电脑连接手机，确认 ADB 可用：\n\n```powershell\nadb devices\n```\n\n然后执行：\n\n```powershell\nadb shell su -c \"cp \u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux \u002Fstorage\u002Femulated\u002F0\u002FDownload\u002Fvmlinux.btf && chmod 0644 \u002Fstorage\u002Femulated\u002F0\u002FDownload\u002Fvmlinux.btf\"\nadb pull \u002Fstorage\u002Femulated\u002F0\u002FDownload\u002Fvmlinux.btf vmlinux.btf\nadb shell su -c \"rm -f \u002Fstorage\u002Femulated\u002F0\u002FDownload\u002Fvmlinux.btf\"\n```\n\n注意：不要用下面这种方式导出：\n\n```powershell\nadb shell su -c \"cat \u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux\" > vmlinux.btf\n```\n\n这种方式容易把二进制 BTF 文件弄坏。必须使用 `adb pull`。\n\n如果导出时报错，通常是以下原因之一：\n\n- 手机没有 root 权限。\n- ADB 没有拿到 root 授权。\n- 当前内核没有 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux`。\n\n### 3. 上传 BTF 到自己的 Fork\n\n打开自己 Fork 的 GitHub 仓库。\n\n进入 `btf` 文件夹，点：\n\n```text\nAdd file -> Upload files\n```\n\n上传刚刚导出的：\n\n```text\nvmlinux.btf\n```\n\n确保上传后的路径是：\n\n```text\nbtf\u002Fvmlinux.btf\n```\n\n然后点 `Commit changes`。\n\n### 4. 运行 GitHub Actions 构建\n\n进入自己 Fork 的仓库：\n\n```text\nActions -> Build KernelSU module -> Run workflow\n```\n\n第一次建议这样选：\n\n```text\nCreate a GitHub Release after building: false\n```\n\n然后点绿色的 `Run workflow`。\n\n第一次构建会比较久，因为 GitHub Actions 需要下载 Android NDK，并编译 `libbpf`、`libelf` 和 `zlib`。\n\n后续构建会使用缓存，通常会快一些。\n\n### 5. 下载构建好的模块\n\nActions 成功后，进入那次运行记录。\n\n在页面底部 `Artifacts` 里下载：\n\n```text\nScenePortHider_Release\n```\n\n下载后解压，里面会有：\n\n```text\nhideSceneport_module.zip\n```\n\n这个就是 KernelSU 模块包。\n\n如果运行 workflow 时把 `Create a GitHub Release after building` 设为 `true`，也可以直接在仓库 `Releases` 页面下载 `hideSceneport_module.zip`。\n\n### 6. 安装模块\n\n把 `hideSceneport_module.zip` 放到手机。\n\n打开 KernelSU Manager：\n\n```text\n模块 -> 从本地安装 -> 选择 hideSceneport_module.zip -> 重启\n```\n\n## 验证是否成功\n\n重启后执行：\n\n```sh\nsu\ncat \u002Fdata\u002Fadb\u002Fmodules\u002FhideSceneport\u002Fhideport.log\nps -A | grep hideport\niptables -S OUTPUT | grep -E \"8765|8788\"\nip6tables -S OUTPUT | grep -E \"8765|8788\"\nexit\n```\n\n正常情况下，`hideport.log` 里应该能看到类似内容：\n\n```text\nhidden port: 8788\nhidden port: 8765\nallowed uid: 0\nallowed uid: 1000\nallowed uid: 2000\nallowed uid: 999\nallowed uid: 10384\nattached connect4 to \u002Fsys\u002Ffs\u002Fcgroup with legacy single attach\nattached connect6 to \u002Fsys\u002Ffs\u002Fcgroup with legacy single attach\nattached getsockname probes to __sys_getsockname\nattached bind probes to __sys_bind\nattached close cleanup probe to __arm64_sys_close\nattached bind4 to \u002Fsys\u002Ffs\u002Fcgroup with legacy single attach\nattached bind6 to \u002Fsys\u002Ffs\u002Fcgroup with legacy single attach\nhideport cgroup-connect loaded\n```\n\n`allowed uid` 的具体数字会因设备、用户空间和 Scene 安装方式不同而变化。关键是日志里应同时出现 Scene UI 的真实 UID 和 `scene-daemon` 所需 UID。\n\n同时 `iptables` \u002F `ip6tables` 里不应该再出现本模块写入的 `8765`、`8788` 规则，Scene 应该可以正常打开。\n\n## 修改配置\n\n默认配置在 `hideport.conf`：\n\n```sh\nPKG=com.omarea.vtools\nPORTS=\"8788 8765\"\nENABLE_EBPF=1\nEXTRA_ALLOWED_UIDS=\"\"\nWAIT_FOR_UID_TIMEOUT=300\nWAIT_FOR_PROCESS=0\n```\n\n一般用户不需要改。\n\n配置说明：\n\n- `PKG`：Scene 包名，默认 `com.omarea.vtools`。\n- `PORTS`：需要隐藏的本机 TCP 端口。\n- `ENABLE_EBPF`：是否启动 eBPF loader。\n- `EXTRA_ALLOWED_UIDS`：额外放行 UID。一般留空；如果 Scene 有特殊辅助进程，可以手动填入。\n- `WAIT_FOR_UID_TIMEOUT`：等待包管理器或运行进程给出真实包 UID 的秒数。\n- `WAIT_FOR_PROCESS`：是否等待 Scene 进程启动后再加载。默认不需要。\n\n模块启动时会等待 `dumpsys package`、`cmd package list packages -U` 或运行进程提供真实 UID。`\u002Fdata\u002Fdata\u002F$PKG` 的 owner 只作为额外补充，不会单独触发 loader 启动，避免开机早期只解析到错误 UID 导致 Scene 自己连不上 daemon。\n\n如果 Scene 包名、端口或运行方式发生变化，可以在构建前修改 `hideport.conf`，然后重新构建模块。\n\n## 本地构建方式\n\n如果你不想用 GitHub Actions，也可以在 Linux 或 WSL 中本地构建。\n\n连接手机后执行：\n\n```sh\nbash tools\u002Fbuild_for_connected_device.sh\n```\n\n脚本会自动：\n\n- 从手机拉取 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux`。\n- 生成 `src\u002Fvmlinux.h`。\n- 下载 Android NDK r25c。\n- 编译 Android arm64 的 `libz.a`、`libelf.a` 和 `libbpf.a`。\n- 编译 `hideport_loader` 和 `hideport.bpf.o`。\n- 打包生成 `..\u002FhideSceneport_module.zip`。\n\n## 常见问题\n\n### 为什么别人构建的包我不能直接用？\n\n因为 eBPF CO-RE 依赖目标内核的 BTF 信息。不同手机或不同内核的结构可能不同。\n\n同机型同系统版本有机会通用，但不保证。最稳妥的方式是用自己的手机导出 `vmlinux.btf` 后重新构建。\n\n### Actions 构建出来的文件大小和本地不一样正常吗？\n\n正常。\n\n`hideport_loader` 是静态链接程序，里面包含 `libbpf`、`libelf`、`zlib` 等依赖。不同构建环境生成的二进制大小可能不同。\n\n只要刷入后日志显示 `hideport cgroup-connect loaded`，并且 Scene 正常打开即可。\n\n### 为什么日志里有一些 ENOENT？\n\n模块会按多个候选内核符号依次尝试挂载 kprobe，例如：\n\n```text\n__sys_close\n__se_sys_close\nsys_close\nSyS_close\n__arm64_sys_close\n```\n\n如果某个符号在当前内核不存在，会看到 `-ENOENT`。只要后面出现实际成功的挂载日志，例如：\n\n```text\nattached close cleanup probe to __arm64_sys_close\n```\n\n就说明功能已经挂上，前面的 `ENOENT` 可以忽略。\n\n### 日志在哪里？\n\n模块日志在：\n\n```text\n\u002Fdata\u002Fadb\u002Fmodules\u002FhideSceneport\u002Fhideport.log\n```\n\n### 刷入后 Scene 打不开怎么办？\n\n先临时停止 loader：\n\n```sh\nsu -c 'for p in $(pidof hideport_loader); do kill \"$p\"; done'\n```\n\n如果停止后 Scene 正常打开，通常说明 UID 白名单漏放行了 Scene 的真实进程 UID。\n\n检查日志和进程：\n\n```sh\nsu -c 'cat \u002Fdata\u002Fadb\u002Fmodules\u002FhideSceneport\u002Fhideport.log'\nsu -c 'ps -A -o USER,PID,PPID,NAME,ARGS | grep -Ei \"scene|omarea|vtools|hideport\"'\nsu -c 'ss -ltnp | grep -E \"8765|8788\"'\n```\n\n正常情况下，日志里的 `allowed uid` 应包含 Scene UI 进程对应的真实 UID。比如进程用户是 `u0_a384`，真实 UID 通常是 `10384`。\n\n如果模块启动太早，旧版可能只解析到 `\u002Fdata\u002Fdata\u002Fcom.omarea.vtools` 的 owner，比如 `999`，导致 Scene UI 自己被当成检测器拦截。新版已经改为等待包管理器或运行进程提供真实 UID 后再启动。\n\n如果仍然漏 UID，可以在 `hideport.conf` 手动添加：\n\n```sh\nEXTRA_ALLOWED_UIDS=\"10384\"\n```\n\n然后重启。\n\n也要确认是否是自己手机导出的 `vmlinux.btf` 构建出来的包。\n\n如果是从别人那里下载的预编译包，建议重新按上面的步骤自助构建。\n\n### 这个模块会写 iptables 规则吗？\n\n不会。当前版本不使用 `iptables` \u002F `ip6tables`，也不再打包 `service.d` 端口隐藏脚本。\n\n如果你看到 `8765`、`8788` 相关 iptables 规则，通常是旧版本残留或其他脚本写入。可以禁用旧模块并完整重启后再检查。\n\n### 安装时报 Kernel BTF mismatch 是什么？\n\n说明这个模块不是用当前手机的 `\u002Fsys\u002Fkernel\u002Fbtf\u002Fvmlinux` 构建出来的。\n\n请重新从当前手机导出 `vmlinux.btf`，上传到自己的 Fork，再跑一次 GitHub Actions。\n\n## 捐赠\n\n如果您觉得这个模块对您有帮助，可以考虑请作者喝杯咖啡：\n\n特别感谢：\n\n- 里（Luna Developers）\n- 欣（Coolapk）\n\n| 微信支付 | 支付宝 |\n| :---: | :---: |\n| ![微信支付](wx.png) | ![支付宝](zfb.jpg) |\n","这是一个KernelSU模块，用于隐藏Scene运行时常用的TCP端口8788和8765。该模块利用eBPF技术在内核层面实现端口行为的隐藏，包括对非白名单应用发起的`connect()`和`bind()`操作进行重定向或临时修改目标端口，并通过kprobe\u002Fkretprobe机制保证`getsockname()`调用的一致性。适用于需要增强隐私保护、防止特定端口被探测到的场景下使用，比如在某些安全要求较高的移动设备上部署Scene应用时。项目不依赖于iptables规则或额外的服务脚本，确保了更广泛的兼容性和更高的效率。",2,"2026-06-11 03:52:49","CREATED_QUERY"]