|
#!/bin/bash |
|
set -euo pipefail |
|
|
|
JAVA="${JAVA:-java}" |
|
ZIPALIGN="${ZIPALIGN:-zipalign}" |
|
APKTOOL="${APKTOOL:-apktool.jar}" |
|
APKSIGNER="${APKSIGNER:-apksigner.jar}" |
|
|
|
if [[ "$#" -ne 2 ]] && [[ "$#" -ne 3 ]]; then |
|
echo "usage: $0 apk_orig apk_out [keystore]" |
|
echo |
|
echo "environment:" |
|
echo " JAVA: ${JAVA}" |
|
echo " ZIPALIGN: ${ZIPALIGN}" |
|
echo " APKTOOL: ${APKTOOL}" |
|
echo " APKSIGNER: ${APKSIGNER}" |
|
echo |
|
echo "note: developed for VNC Viewer 3.7.1.44443" |
|
exit 2 |
|
fi |
|
|
|
APK_ORIG="$1" |
|
APK_OUT="$2" |
|
KEYSTORE="${3:-}" |
|
|
|
if ! command -v "${ZIPALIGN}" &>/dev/null; then |
|
echo "Please install zipalign." 1>&2 |
|
exit 1 |
|
fi |
|
|
|
if ! command -v "${JAVA}" &>/dev/null; then |
|
echo "Please install Java." 1>&2 |
|
exit 1 |
|
fi |
|
|
|
if ! test -f "${APKTOOL}"; then |
|
echo "Please download APKTool v2.5.0 or newer." 1>&2 |
|
exit 1 |
|
fi |
|
|
|
if ! test -f "${APKSIGNER}"; then |
|
echo "Please download apksigner." 1>&2 |
|
exit 1 |
|
fi |
|
|
|
TMPDIR=".vncviewer-tmp" |
|
rm -rf "${TMPDIR}" |
|
mkdir "${TMPDIR}" |
|
|
|
echo |
|
echo '> Decompiling APK' |
|
"${JAVA}" -jar "${APKTOOL}" d --no-res --output "${TMPDIR}/apk" "${APK_ORIG}" |
|
|
|
echo |
|
echo '> Patching APK :: Fix double-backspace bug' |
|
patch -p1 -d "${TMPDIR}/apk" <<EOF |
|
diff --git a/smali/com/realvnc/viewer/android/ui/input/f.smali b/smali/com/realvnc/viewer/android/ui/input/f.smali |
|
index d72129f..d670d95 100644 |
|
--- a/smali/com/realvnc/viewer/android/ui/input/f.smali |
|
+++ b/smali/com/realvnc/viewer/android/ui/input/f.smali |
|
@@ -473,16 +473,6 @@ |
|
|
|
if-ne v0, v2, :cond_11 |
|
|
|
- .line 48 |
|
- invoke-virtual {p1}, Landroid/view/KeyEvent;->getAction()I |
|
- |
|
- move-result p1 |
|
- |
|
- if-ne p1, v1, :cond_12 |
|
- |
|
- .line 49 |
|
- invoke-virtual {p0}, Lcom/realvnc/viewer/android/ui/input/f;->a()V |
|
- |
|
goto :goto_7 |
|
|
|
.line 50 |
|
EOF |
|
|
|
echo |
|
echo '> Patching APK :: Write all log messages to logcat' |
|
if [[ "${DEBUG:-0}" -ne "1" ]]; then |
|
echo "disabled (set DEBUG=1 to enable)" |
|
else |
|
patch -p1 -d "${TMPDIR}/apk" <<EOF |
|
diff --git a/smali/com/realvnc/viewer/android/app/w6/p.smali b/smali/com/realvnc/viewer/android/app/w6/p.smali |
|
index 5b8fbbb..1b8d0c1 100644 |
|
--- a/smali/com/realvnc/viewer/android/app/w6/p.smali |
|
+++ b/smali/com/realvnc/viewer/android/app/w6/p.smali |
|
@@ -91,47 +91,8 @@ |
|
|
|
.method public static declared-synchronized a(ILjava/lang/String;Ljava/lang/String;)V |
|
.locals 2 |
|
- |
|
- const-class v0, Lcom/realvnc/viewer/android/app/w6/p; |
|
- |
|
- monitor-enter v0 |
|
- |
|
- .line 7 |
|
- :try_start_0 |
|
- new-instance v1, Ljava/lang/StringBuilder; |
|
- |
|
- invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V |
|
- |
|
- invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; |
|
- |
|
- const-string p2, "" |
|
- |
|
- invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; |
|
- |
|
- invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; |
|
- |
|
- move-result-object p2 |
|
- |
|
- .line 8 |
|
- new-instance v1, Lcom/realvnc/viewer/android/app/w6/o; |
|
- |
|
- invoke-direct {v1, p0, p1, p2}, Lcom/realvnc/viewer/android/app/w6/o;-><init>(ILjava/lang/String;Ljava/lang/String;)V |
|
- |
|
- invoke-static {v1}, Lcom/realvnc/viewer/android/model/e2;->a(Ljava/lang/Runnable;)Z |
|
- :try_end_0 |
|
- .catchall {:try_start_0 .. :try_end_0} :catchall_0 |
|
- |
|
- .line 9 |
|
- monitor-exit v0 |
|
- |
|
+ invoke-static {p1, p2}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I |
|
return-void |
|
- |
|
- :catchall_0 |
|
- move-exception p0 |
|
- |
|
- monitor-exit v0 |
|
- |
|
- throw p0 |
|
.end method |
|
|
|
.method public static a(Z)V |
|
EOF |
|
fi |
|
|
|
echo |
|
echo '> Building APK' |
|
"${JAVA}" -jar "${APKTOOL}" b --no-res --output "${TMPDIR}/patched.apk" "${TMPDIR}/apk" |
|
|
|
echo |
|
echo '> Aligning APK' |
|
"${ZIPALIGN}" -p 4 "${TMPDIR}/patched.apk" "${TMPDIR}/aligned.apk" |
|
|
|
echo |
|
echo '> Signing APK' |
|
if [[ -z "${KEYSTORE}" ]]; then |
|
test -f "default.jks" || keytool -genkeypair -v -keystore "default.jks" -keyalg "RSA" -storepass "default" -alias "default" -dname "CN=VNCViewer-Android-Patch, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CA" |
|
"${JAVA}" -jar "${APKSIGNER}" sign --min-sdk-version=23 --ks "default.jks" --ks-pass "pass:default" --pass-encoding utf-8 --out "${TMPDIR}/signed.apk" "${TMPDIR}/aligned.apk" |
|
else |
|
"${JAVA}" -jar "${APKSIGNER}" sign --min-sdk-version=23 --ks "${KEYSTORE}" --out "${TMPDIR}/signed.apk" "${TMPDIR}/aligned.apk" |
|
fi |
|
|
|
echo |
|
echo '> Cleanup' |
|
mv "${TMPDIR}/signed.apk" "${APK_OUT}" |
|
rm -rf "${TMPDIR}" |
|
|
|
echo |
|
echo "Successfully patched ${APK_OUT} from ${APK_ORIG}." |
|
exit 0 |
For VNC Viewer 4.x, see https://github.com/pgaskin/vncpatch.