From bf98b6d0024830ec943bb1ab0147808808e137f8 Mon Sep 17 00:00:00 2001 From: FlintyLemming Date: Sat, 28 Feb 2026 11:03:57 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(av1-transfer):=20?= =?UTF-8?q?replace=20setproctitle=20with=20ctypes=20to=20fully=20hide=20cm?= =?UTF-8?q?dline=20args?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the setproctitle dependency. Use prctl(PR_SET_NAME) to change /proc/self/comm and directly overwrite argv memory via Py_GetArgcArgv to clear /proc/self/cmdline, so ps aux shows no arguments. Co-Authored-By: Claude Sonnet 4.6 --- av1-transfer/main.py | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/av1-transfer/main.py b/av1-transfer/main.py index af7de67..fe97877 100644 --- a/av1-transfer/main.py +++ b/av1-transfer/main.py @@ -17,13 +17,15 @@ AV1 视频批量转码脚本 """ import argparse +import ctypes +import ctypes.util import queue import shutil import subprocess +import sys from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path -import setproctitle from tqdm import tqdm # ================= 配置区域 ================= @@ -35,6 +37,42 @@ VIDEO_EXTS = {".mp4", ".mkv", ".mov", ".avi", ".flv", ".ts", ".webm"} SLOT_BAR_FORMAT = "{desc:<50} {percentage:3.0f}%|{bar}| {n:.0f}/{total:.0f}s" +def _set_proc_title(title: str) -> None: + """ + 通过两种方式彻底隐藏进程命令行: + 1. prctl(PR_SET_NAME) — 改 /proc/self/comm(top 默认显示的短名) + 2. 直接覆盖 argv 内存 — 改 /proc/self/cmdline(ps aux COMMAND 列) + """ + # 1. 改短名(/proc/self/comm,最多 15 字节) + try: + libc_name = ctypes.util.find_library("c") + if libc_name: + libc = ctypes.CDLL(libc_name, use_errno=True) + libc.prctl(15, title.encode()[:15], 0, 0, 0) # PR_SET_NAME = 15 + except Exception: + pass + + # 2. 覆盖 argv 内存,清除 /proc/self/cmdline 里的参数 + try: + argc = ctypes.c_int(0) + argv = ctypes.POINTER(ctypes.c_char_p)() + ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(argc), ctypes.byref(argv)) + if argc.value == 0: + return + # argv 字符串在内存中连续排列,计算总占用字节数 + start = ctypes.cast(argv[0], ctypes.c_void_p).value + end = ctypes.cast(argv[argc.value - 1], ctypes.c_void_p).value + end += len(argv[argc.value - 1]) + 1 + size = end - start + # 用 title 填充开头,其余全部清零 + enc = title.encode()[:size - 1] + buf = (ctypes.c_char * size).from_address(start) + buf[:len(enc)] = enc + buf[len(enc):] = b"\x00" * (size - len(enc)) + except Exception: + pass + + def get_duration(input_path): """用 ffprobe 获取视频时长(秒),失败返回 None""" result = subprocess.run( @@ -203,7 +241,7 @@ def main(): print(f"共发现 {len(tasks)} 个文件,准备使用 {max_workers} 个并行任务进行转码...") if process_name: - setproctitle.setproctitle(process_name) + _set_proc_title(process_name) print(f"进程别名: {process_name}") # 初始化进度条