apply_a16_fix.sh
4.13 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/bash
# LSPosed A16 Fix — apply the JNINativeInterface runtime-size patch
# Usage: bash apply_a16_fix.sh <path-to-LSPosed-repo>
# Example: bash apply_a16_fix.sh ~/LSPosed
set -e
REPO="${1:-.}"
HEADER="$REPO/zygisk/src/main/cpp/include/ipc_bridge.h"
CPP="$REPO/zygisk/src/main/cpp/ipc_bridge.cpp"
if [ ! -f "$HEADER" ] || [ ! -f "$CPP" ]; then
echo "ERROR: LSPosed source not found at $REPO"
echo "Clone first: git clone --depth 1 --recursive https://github.com/JingMatrix/LSPosed.git"
exit 1
fi
echo "=== Applying A16 JNINativeInterface runtime-size fix ==="
# === Patch 1: ipc_bridge.h — change stack-allocated table to pointer ===
echo "[1/2] Patching $HEADER ..."
# Create backup
cp "$HEADER" "$HEADER.bak"
python3 -c "
import re
with open('$HEADER', 'r') as f:
content = f.read()
old = ' // A complete copy of the original JNI function table, with our hook installed.\n JNINativeInterface native_interface_hook_{};'
new = ''' // A complete copy of the original JNI function table, with our hook installed.
// Uses runtime-size allocation to support A16+ where ART added new JNI functions.
JNINativeInterface* native_interface_hook_ = nullptr;
size_t table_size_ = 0;'''
if old in content:
content = content.replace(old, new)
with open('$HEADER', 'w') as f:
f.write(content)
print(' ✓ ipc_bridge.h patched')
else:
print(' ⚠ ipc_bridge.h — pattern not found, may already be patched')
"
# === Patch 2: ipc_bridge.cpp — use reserved0 for runtime size ===
echo "[2/2] Patching $CPP ..."
cp "$CPP" "$CPP.bak"
python3 -c "
with open('$CPP', 'r') as f:
content = f.read()
old = ''' // --- Step 3: Install the hook ---
// Make a full copy of the existing JNI function table.
memcpy(&native_interface_hook_, env->functions, sizeof(JNINativeInterface));
// Store a pointer to the original function we are about to replace.
call_boolean_method_v_backup_ = env->functions->CallBooleanMethodV;
// Overwrite the function pointer in our copy with our hook.
native_interface_hook_.CallBooleanMethodV = &CallBooleanMethodV_Hook;
// Atomically swap the process's JNI function table with our modified one.
set_table_override_func(&native_interface_hook_);'''
new = ''' // --- Step 3: Install the hook ---
// Get the ACTUAL runtime size of the JNI function table.
// Android 16 ART adds new JNI functions that increase the table size.
// Using compile-time sizeof(JNINativeInterface) truncates the copy,
// causing crashes when ART calls new functions via garbage pointers.
table_size_ = (size_t)env->functions->reserved0;
if (table_size_ == 0 || table_size_ < sizeof(JNINativeInterface)) {
table_size_ = sizeof(JNINativeInterface);
}
LOGI(\"JNI table runtime size: %zu (compile-time: %zu)\", table_size_, sizeof(JNINativeInterface));
// Allocate and copy with runtime size
native_interface_hook_ = (JNINativeInterface*)malloc(table_size_);
if (!native_interface_hook_) {
LOGE(\"Failed to allocate JNI hook table.\");
return;
}
memcpy(native_interface_hook_, env->functions, table_size_);
// Store a pointer to the original function we are about to replace.
call_boolean_method_v_backup_ = native_interface_hook_->CallBooleanMethodV;
// Overwrite the function pointer in our copy with our hook.
native_interface_hook_->CallBooleanMethodV = &CallBooleanMethodV_Hook;
// Atomically swap the process's JNI function table with our modified one.
set_table_override_func(native_interface_hook_);'''
if old in content:
content = content.replace(old, new)
with open('$CPP', 'w') as f:
f.write(content)
print(' ✓ ipc_bridge.cpp patched')
else:
print(' ⚠ ipc_bridge.cpp — pattern not found, may already be patched')
"
echo ""
echo "=== Done. Building ==="
echo ""
echo "To build:"
echo " export ANDROID_HOME=/path/to/android-sdk"
echo " cd $REPO"
echo " ./gradlew :zygisk:assembleRelease"
echo ""
echo "Output: zygisk/build/outputs/apk/release/zygisk-release.apk"
echo "The fixed zygisk .so inside can replace:"
echo " /data/adb/modules/zygisk_vector/zygisk/arm64-v8a.so"