https://drive.google.com/file/d/1N0xb9RldmiU8eVSHh8_79Tm1Nhtbf6yc/view?usp=drivesdk
patch script
(everything we did, including background app kill)
#!/bin/bash
source $(dirname $(realpath "$0"))/_.sh
LIB='services.jar'
# PATCH 1: isOversea() - Always return true
PATCH_IDENTITY=adb_bypass_is_oversea_01
FILE="com/android/server/pm/PackageManagerShellCommand.smali"
REGEX='\.method private isOversea\(\)Z.*?\.locals 2\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x1
return v0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 2: isAdbInstallDisallowed() - Always return false
PATCH_IDENTITY=adb_bypass_is_adb_disallowed_02
FILE="com/android/server/pm/Settings.smali"
REGEX='\.method static isAdbInstallDisallowed\(Lcom\/android\/server\/pm\/UserManagerService;I\)Z.*?\.locals 1\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
return v0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 3: PackageInstallerService - Bypass no_install_apps check
PATCH_IDENTITY=adb_bypass_pkg_installer_03
FILE="com/android/server/pm/PackageInstallerService.smali"
REGEX='invoke-virtual \{v1, v12, v2\}, Lcom\/android\/server\/pm\/PackageManagerService;->isUserRestricted\(ILjava\/lang\/String;\)Z\n\n move-result v1\n'
PATCH=$(cat << 'EOF'
const/4 v1, 0x0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 4: PackageManagerService - Bypass no_install_apps check
PATCH_IDENTITY=adb_bypass_pkg_mgr_svc_04
FILE="com/android/server/pm/PackageManagerService.smali"
REGEX='invoke-virtual \{v8, v10, v0\}, Lcom\/android\/server\/pm\/PackageManagerService;->isUserRestricted\(ILjava\/lang\/String;\)Z\n\n move-result v0\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 5: PackageManagerServiceUtils - Bypass enforceShellRestriction
PATCH_IDENTITY=adb_bypass_pkg_utils_05
FILE="com/android/server/pm/PackageManagerServiceUtils.smali"
REGEX='\.method public static enforceShellRestriction\(Landroid\/os\/UserManagerInternal;Ljava\/lang\/String;II\)V\n \.locals 3\n \.param p0, "userManager".*?\n \.param p1, "restriction".*?\n \.param p2, "callingUid".*?\n \.param p3, "userHandle".*?\n\n'
PATCH=$(cat << 'EOF'
return-void
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 6: UserController - Bypass enforceShellRestriction method
PATCH_IDENTITY=adb_bypass_user_ctrl_shell_06
FILE="com/android/server/am/UserController.smali"
REGEX='\.method private enforceShellRestriction\(Ljava\/lang\/String;I\)V\n \.locals 3\n \.param p1, "restriction".*?\n \.param p2, "userId".*?\n\n'
PATCH=$(cat << 'EOF'
return-void
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 7: UserController - Bypass inline no_debugging_features check
PATCH_IDENTITY=adb_bypass_user_ctrl_debug_07
FILE="com/android/server/am/UserController.smali"
REGEX='invoke-virtual \{v6, v0, v12\}, Lcom\/android\/server\/am\/UserController;->hasUserRestriction\(Ljava\/lang\/String;I\)Z\n\n move-result v0\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 8: PackageManagerService - isUserRestricted() always return false
PATCH_IDENTITY=adb_bypass_is_user_restricted_08
FILE="com/android/server/pm/PackageManagerService.smali"
REGEX='\.method isUserRestricted\(ILjava\/lang\/String;\)Z\n \.locals 3\n \.param p1, "userId".*?\n \.param p2, "restrictionKey".*?\n\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
return v0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 9: UserManagerService$LocalService - hasUserRestriction() bypass for install restrictions
PATCH_IDENTITY=adb_bypass_local_svc_restriction_09
FILE="com/android/server/pm/UserManagerService\$LocalService.smali"
REGEX='\.method public hasUserRestriction\(Ljava\/lang\/String;I\)Z\n \.locals 3\n \.param p1, "restrictionKey".*?\n \.param p2, "userId".*?\n\n'
PATCH=$(cat << 'EOF'
const-string v0, "no_debugging_features"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_restriction
const-string v0, "no_install_apps"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_restriction
const-string v0, "no_install_unknown_sources"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_restriction
const-string v0, "no_install_unknown_sources_globally"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_restriction
goto :original_check
:bypass_restriction
const/4 v0, 0x0
return v0
:original_check
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 10: UserManagerService - hasUserRestriction() bypass for install restrictions
PATCH_IDENTITY=adb_bypass_um_svc_restriction_10
FILE="com/android/server/pm/UserManagerService.smali"
REGEX='\.method public hasUserRestriction\(Ljava\/lang\/String;I\)Z\n \.locals 1\n \.param p1, "restrictionKey".*?\n \.param p2, "userId".*?\n\n'
PATCH=$(cat << 'EOF'
const-string v0, "no_debugging_features"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_um
const-string v0, "no_install_apps"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_um
const-string v0, "no_install_unknown_sources"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_um
const-string v0, "no_install_unknown_sources_globally"
invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-nez v0, :bypass_um
goto :original_um_check
:bypass_um
const/4 v0, 0x0
return v0
:original_um_check
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 11: AdbService - Bypass Duoqin Guard check in systemReady()
PATCH_IDENTITY=adb_bypass_duoqin_guard_11
FILE="com/android/server/adb/AdbService.smali"
REGEX='invoke-static \{v0\}, Lcom\/duoqin\/guard\/Guard;->isDuoqinGuardEnable\(Landroid\/content\/ContentResolver;\)Z\n\n move-result v0\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 12: AdbSettingsObserver - Bypass Duoqin Guard check in onChange()
PATCH_IDENTITY=adb_bypass_duoqin_observer_12
FILE="com/android/server/adb/AdbService\$AdbSettingsObserver.smali"
REGEX='invoke-static \{v0\}, Lcom\/duoqin\/guard\/Guard;->isDuoqinGuardEnable\(Landroid\/content\/ContentResolver;\)Z\n\n move-result v0\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 13: ActivityTaskManagerService - isActivityDisabledByGuard() always return false
# This bypasses the Duoqin Guard activity blocking mechanism
PATCH_IDENTITY=adb_bypass_activity_guard_13
FILE="com/android/server/wm/ActivityTaskManagerService.smali"
REGEX='\.method isActivityDisabledByGuard\(Ljava\/lang\/String;\)Z\n \.locals 1\n \.param p1, "component".*?\n\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x0
return v0
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 14: PackageManagerShellCommand.onCommand() - Bypass IS_DEBUGGABLE check
# This is the ROOT CAUSE - pm commands check Build.IS_DEBUGGABLE and reject all on user builds
# We insert const/4 v0, 0x1 right after sget-boolean, BEFORE the if-nez check
PATCH_IDENTITY=adb_bypass_debuggable_check_14
FILE="com/android/server/pm/PackageManagerShellCommand.smali"
REGEX='sget-boolean v0, Landroid\/os\/Build;->IS_DEBUGGABLE:Z\n\n const\/4 v1, 0x1\n'
PATCH=$(cat << 'EOF'
const/4 v0, 0x1
EOF
)
patch_insert_after "$PATCH_IDENTITY" "$LIB" "$REGEX" "$PATCH" "$FILE"
# PATCH 15: ActivityManagerService$LocalService - Replace killProcessesForRemovedTask method
PATCH_IDENTITY=kill_processes_fix_15
FILE="com/android/server/am/ActivityManagerService\$LocalService.smali"
METHOD_SIG=".method public killProcessesForRemovedTask(Ljava/util/ArrayList;)V"
NEW_METHOD=$(cat << 'ENDMETHOD'
.method public killProcessesForRemovedTask(Ljava/util/ArrayList;)V
.locals 7
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Ljava/util/ArrayList<",
"Ljava/lang/Object;",
">;)V"
}
.end annotation
.line 19460
iget-object v0, p0, Lcom/android/server/am/ActivityManagerService$LocalService;->this$0:Lcom/android/server/am/ActivityManagerService;
monitor-enter v0
:try_start_0
invoke-static {}, Lcom/android/server/am/ActivityManagerService;->boostPriorityForLockedSection()V
.line 19461
const/4 v1, 0x0
move v2, v1
:goto_0
invoke-virtual {p1}, Ljava/util/ArrayList;->size()I
move-result v3
if-ge v2, v3, :cond_1
.line 19462
nop
.line 19463
invoke-virtual {p1, v2}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;
move-result-object v3
check-cast v3, Lcom/android/server/wm/WindowProcessController;
.line 19464
iget-object v3, v3, Lcom/android/server/wm/WindowProcessController;->mOwner:Ljava/lang/Object;
check-cast v3, Lcom/android/server/am/ProcessRecord;
.line 19465
iget v4, v3, Lcom/android/server/am/ProcessRecord;->setSchedGroup:I
if-nez v4, :cond_0
iget-object v4, v3, Lcom/android/server/am/ProcessRecord;->curReceivers:Landroid/util/ArraySet;
.line 19466
invoke-virtual {v4}, Landroid/util/ArraySet;->isEmpty()Z
move-result v4
if-eqz v4, :cond_0
.line 19467
const-string/jumbo v4, "remove task"
const/16 v5, 0xa
const/4 v6, 0x1
invoke-virtual {v3, v4, v5, v1, v6}, Lcom/android/server/am/ProcessRecord;->kill(Ljava/lang/String;IIZ)V
goto :goto_1
.line 19472
:cond_0
const-string/jumbo v4, "remove task"
iput-object v4, v3, Lcom/android/server/am/ProcessRecord;->waitingToKill:Ljava/lang/String;
.line 19461
:goto_1
add-int/lit8 v2, v2, 0x1
goto :goto_0
.line 19475
:cond_1
monitor-exit v0
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0
invoke-static {}, Lcom/android/server/am/ActivityManagerService;->resetPriorityAfterLockedSection()V
.line 19476
return-void
.line 19475
:catchall_0
move-exception p1
:try_start_1
monitor-exit v0
:try_end_1
.catchall {:try_start_1 .. :try_end_1} :catchall_0
invoke-static {}, Lcom/android/server/am/ActivityManagerService;->resetPriorityAfterLockedSection()V
throw p1
.end method
ENDMETHOD
)
patch_replace_method "$PATCH_IDENTITY" "$LIB" "$METHOD_SIG" "$NEW_METHOD" "$FILE"
echo ""
echo "Complete"
_.sh
#!/bin/bash
patch_banner() {
local identity=$1
echo " ##### jarpatcher:$identity"
}
patch_remove() {
local identity="$1"
local file="$2"
local marker=$(patch_banner "$identity")
perl -i -0777 -pe 's/('"\n$marker"'.*'"$marker\n\n"')//gs' "$file"
}
patch_insert_after() {
local identity=$1
local marker=$(patch_banner "$identity")
local lib="$2"
local regx="$3"
local code=$(printf '%s' "$4" | sed 's/[][\.*^$(){}?+|\/]/\\&/g')
local class="$5"
SCRIPT_PATH=$(dirname $(realpath "$0"))
LIB_PATH="$SCRIPT_PATH""/../$lib.smali"
SMALI_PATH=$(find $LIB_PATH | grep "$class")
file=$SMALI_PATH
if [ ! -e "$file" ]; then
echo "Could not find '$class' in '$lib' to apply patch '$identity'. Make sure '$lib' library pulled and decompiled!"
return
fi
patch_remove "$identity" "$file"
if grep -q $identity $file; then
echo "Could not remove old patch '$identity'!"
return
fi
perl -i -0777 -pe 's/('"$regx"')/$1'"\n$marker\n$code\n$marker\n\n"'/s' "$file"
if grep -q $identity $file; then
echo "Patch '$identity' successfully applied!"
else
echo "Patch '$identity' was not applied. Probably smali code was changed and do not match signature anymore."
fi
}
# Replace an entire method with new content
# Uses temp file approach to avoid regex escaping issues
patch_replace_method() {
local identity=$1
local lib="$2"
local method_sig="$3" # e.g., ".method public killProcessesForRemovedTask"
local new_method="$4"
local class="$5"
SCRIPT_PATH=$(dirname $(realpath "$0"))
LIB_PATH="$SCRIPT_PATH""/../$lib.smali"
SMALI_PATH=$(find $LIB_PATH | grep "$class")
file=$SMALI_PATH
if [ ! -e "$file" ]; then
echo "Could not find '$class' in '$lib' to apply patch '$identity'. Make sure '$lib' library pulled and decompiled!"
return
fi
# Write new method to temp file
local tmp_method=$(mktemp)
echo "$new_method" > "$tmp_method"
# Use awk to replace the method
awk -v sig="$method_sig" -v newfile="$tmp_method" '
BEGIN { in_method = 0 }
$0 ~ sig { in_method = 1; while ((getline line < newfile) > 0) print line; close(newfile) }
in_method && /^\.end method/ { in_method = 0; next }
!in_method { print }
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
rm -f "$tmp_method"
if grep -q "$method_sig" "$file"; then
echo "Patch '$identity' successfully applied!"
else
echo "Patch '$identity' was not applied. Method not found after replacement."
fi
}
# Method for logging some strings in logcat
# (be careful, some smali methods do not have v0 available)
android_logcat() {
LOG_IDENTITY=$1
RANDOM_NUMBER=$(( RANDOM % 100000 ))
LABEL="99$RANDOM_NUMBER"
CODE=$(cat << EOF
:try_start_$LABEL
const-string v0, "$LOG_IDENTITY"
invoke-static {v0, v0}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)I
:try_end_$LABEL
.catchall {:try_start_$LABEL .. :try_end_$LABEL} :catchall_$LABEL
goto :try_exit_$LABEL
:catchall_$LABEL
move-exception v0
:try_exit_$LABEL
EOF
)
echo "$CODE"
}