wechat_send_20260706.sh
3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/bin/bash
# wechat_send.sh — unified WeChat send CLI via the internal hook
#
# Usage:
# ./wechat_send.sh text <wxid> <message>
# ./wechat_send.sh image <wxid> <device_image_path>
# ./wechat_send.sh voice <wxid> <local_silk_path> [duration_ms]
#
# All send operations go through the wechathook LSPosed module's internal API,
# which calls WeChat's own w11.r0/w11.s1 factory — no UI simulation.
# <wxid>: talker id as stored in WeChat DB (e.g. 'filehelper', 'wxid_xxx').
# IMPORTANT: test-only with 'filehelper' to avoid account risk.
#
# Voice notes:
# <local_silk_path> — local SILK V3 file (Tencent prefix \x02#!SILK_V3).
# [duration_ms] — playback duration in ms (default: 3000).
# The script pushes the SILK to WeChat's cache dir and fires the broadcast.
#
# Examples:
# ./wechat_send.sh text filehelper "hello world"
# ./wechat_send.sh image filehelper /tmp/screenshot.png
# ./wechat_send.sh voice filehelper /tmp/tts_out.silk 4617
set -e
ADB="${ADB:-adb}"
WECHAT_CACHE="/data/data/com.tencent.mm/cache/hook_voice_src.amr"
usage() {
echo "Usage: $0 text <wxid> <message>"
echo " $0 image <wxid> <device_path>"
echo " $0 voice <wxid> <local_silk_path> [duration_ms]"
exit 1
}
[ $# -lt 3 ] && usage
CMD="$1"; WXID="$2"; shift 2
case "$CMD" in
text)
PAYLOAD="$*"
B64_WXID=$(printf '%s' "$WXID" | base64 | tr -d '\n')
B64_TEXT=$(printf '%s' "$PAYLOAD" | base64 | tr -d '\n')
INNER=$(printf 'TO=$(printf "%%s" "%s" | base64 -d); TEXT=$(printf "%%s" "%s" | base64 -d); am broadcast -a com.hermes.wechat.SEND_MSG_INTERNAL --es to "$TO" --es text "$TEXT"' \
"$B64_WXID" "$B64_TEXT")
B64_INNER=$(printf '%s' "$INNER" | base64 | tr -d '\n')
echo "Sending text to $WXID..."
$ADB shell "su -c 'echo $B64_INNER | base64 -d | sh'"
;;
image)
IMAGE_PATH="$1"
EXT="${IMAGE_PATH##*.}"
SHARE="/sdcard/wechat_share_tmp.$EXT"
MIME="image/jpeg"
[ "$EXT" = "png" ] && MIME="image/png"
echo "Copying image to $SHARE..."
$ADB shell "su -c 'cp \"$IMAGE_PATH\" \"$SHARE\" && chmod 644 \"$SHARE\"'"
echo "Sending image to $WXID via share intent..."
$ADB shell "am start -a android.intent.action.SEND -t $MIME \
--eu android.intent.extra.STREAM 'file://$SHARE' \
-p com.tencent.mm"
echo "WeChat share intent fired. Select '$WXID' in WeChat's contact picker and tap 发送."
;;
voice)
SILK_PATH="$1"
DURATION="${2:-3000}"
[ -z "$SILK_PATH" ] && usage
[ ! -f "$SILK_PATH" ] && { echo "File not found: $SILK_PATH"; exit 1; }
echo "Pushing SILK to WeChat cache..."
$ADB push "$SILK_PATH" /sdcard/hook_voice_tmp.amr
$ADB shell "su -c 'cp /sdcard/hook_voice_tmp.amr $WECHAT_CACHE && chmod 644 $WECHAT_CACHE && chown u0_a330:u0_a330 $WECHAT_CACHE && rm /sdcard/hook_voice_tmp.amr'"
echo "Sending voice to $WXID (duration=${DURATION}ms)..."
$ADB shell "su -c 'am broadcast -a com.hermes.wechat.SEND_VOICE_INTERNAL --es to $WXID --es src_path $WECHAT_CACHE --ei duration $DURATION'"
;;
*)
echo "Unknown command: $CMD"
usage
;;
esac