Files
workphone-sdk/sdk/scripts/_hook_smoke.py

137 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# 工作手机 · Frida 主控通道·实机冒烟脚本(一次性跑完 8 项验证)
# 用法python3 sdk/scripts/_hook_smoke.py <device_serial>
import json, sys, urllib.request, urllib.parse, time
DEVICE = sys.argv[1] if len(sys.argv) > 1 else 'xgfe65eimrrofyws'
BASE = 'http://127.0.0.1:8899'
def get(path, params=None):
url = f'{BASE}{path}'
if params:
url += '?' + urllib.parse.urlencode(params)
with urllib.request.urlopen(url, timeout=60) as r:
return json.loads(r.read())
def post(path, body):
req = urllib.request.Request(
f'{BASE}{path}',
data=json.dumps(body).encode(),
headers={'Content-Type': 'application/json'},
method='POST',
)
with urllib.request.urlopen(req, timeout=120) as r:
return json.loads(r.read())
def section(title):
print('\n' + '=' * 60)
print(f' {title}')
print('=' * 60)
def show(label, value, limit=200):
s = json.dumps(value, ensure_ascii=False)
if len(s) > limit:
s = s[:limit] + ' …(truncated)'
print(f'{label}{s}')
# 1) probe
section('1) /api/v3/hook/probe — Hook 探测')
probe = get(f'/api/v3/hook/probe/{DEVICE}')
show('supports_hook', probe.get('supports_hook'))
show('frida_version', probe.get('frida_version'))
show('wechat_version', probe.get('wechat_version'))
show('profile.nickname', probe.get('profile', {}).get('profile', {}).get('nickname'))
# 2) actions 清单
section('2) /api/v3/hook/actions — 全部动作清单')
acts = get('/api/v3/hook/actions')
show('total_actions', acts.get('total_actions'))
show('total_modules', acts.get('total_modules'))
# 3) 一次性取数
section('3) /api/v3/hook/data — 取微信资料/联系人/群/消息/标签')
data = get(f'/api/v3/hook/data/{DEVICE}',
{'modules': 'profile,contacts,groups,messages,labels'})
core = data.get('data', {})
def _list(node, key1, key2=None):
inner = node.get('data', node)
if key2 and isinstance(inner, dict) and key2 in inner:
return inner[key2]
if isinstance(inner, dict) and key1 in inner:
return inner[key1]
if isinstance(inner, dict) and 'data' in inner and isinstance(inner['data'], list):
return inner['data']
return inner if isinstance(inner, list) else []
contacts = _list(core['contacts'], 'contacts')
groups = _list(core['groups'], 'groups')
messages = _list(core['messages'], 'messages')
labels = _list(core['labels'], 'labels')
print(f'contacts : {len(contacts)}')
print(f'groups : {len(groups)}')
print(f'messages : {len(messages)}')
print(f'labels : {len(labels)}')
remark = [c for c in contacts if c.get('remark')]
namedgrp = [g for g in groups if g.get('name')]
print(f' - 有备注联系人: {len(remark)} 例子:',
', '.join((c.get('remark') or '?')[:24] for c in remark[:5]))
print(f' - 已命名群 : {len(namedgrp)} 例子:',
', '.join((g.get('name') or '?')[:24] for g in namedgrp[:5]))
print(f' - 标签 : {len(labels)} 例子:',
', '.join((l.get('name') or '?')[:18] for l in labels[:8]))
# 4) hookStatus / getMoments / getWechatVersion 直调
section('4) /api/v3/hook/execute — hookStatus + getWechatVersion')
hs = post('/api/v3/hook/execute', {
'device_id': DEVICE, 'platform': 'wechat',
'action': 'get_hook_status', 'params': {}, 'hook_only': True
})
show('hookStatus', hs)
gv = post('/api/v3/hook/execute', {
'device_id': DEVICE, 'platform': 'wechat',
'action': 'get_wechat_version', 'params': {}, 'hook_only': True
})
show('getWechatVersion', gv)
# 5) 朋友圈
section('5) /api/v3/hook/execute — getMoments(limit=3)')
mm = post('/api/v3/hook/execute', {
'device_id': DEVICE, 'platform': 'wechat',
'action': 'get_moments', 'params': {'limit': 3}, 'hook_only': True
})
show('getMoments', mm, 400)
# 6) 真发一条消息到文件传输助手
section('6) /api/v3/hook/execute — send_message → 文件传输助手')
ts = time.strftime('%H:%M:%S')
send = post('/api/v3/hook/execute', {
'device_id': DEVICE, 'platform': 'wechat',
'action': 'send_message',
'params': {
'to_id': 'filehelper',
'content': f'[E2E] Frida 主控通道 实机冒烟 {ts}',
'msg_type': 'text',
},
'hook_only': True
})
show('send_message', send)
# 7) 拉一条最近消息证明 read-back
section('7) /api/v3/hook/execute — get_recent_messages(limit=1)')
rm = post('/api/v3/hook/execute', {
'device_id': DEVICE, 'platform': 'wechat',
'action': 'get_recent_messages', 'params': {'limit': 1}, 'hook_only': True
})
show('get_recent_messages', rm, 400)
# 8) 走标准 unified channel=hook 的 sendMessage验证存客宝侧路径
section('8) /api/v3/message/send channel=hook (存客宝标准入口)')
um = post('/api/v3/message/send', {
'device_id': DEVICE, 'platform': 'wechat', 'to_id': 'filehelper',
'content': f'[E2E] unified channel=hook {ts}',
'msg_type': 'text', 'channel': 'hook'
})
show('unified.sendMessage', um, 400)
print('\n ✅ Hook 主控冒烟测试完成')