chore: rooting bl9000 with etc hosts

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-11-17 11:14:38 +01:00
parent dfe079c219
commit bd0d87b276
3 changed files with 1274 additions and 644 deletions

View File

@ -40,7 +40,7 @@ log() {
local msg="$1" local msg="$1"
echo -e "${GREEN}[$(timestamp)]${NC} $msg" echo -e "${GREEN}[$(timestamp)]${NC} $msg"
if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then
echo "[$(timestamp)] $msg" >> "$LOG_FILE" 2>&1 || true echo "[$(timestamp)] $msg" >>"$LOG_FILE" 2>&1 || true
fi fi
} }
@ -48,7 +48,7 @@ warn() {
local msg="$1" local msg="$1"
echo -e "${YELLOW}[WARN]${NC} $msg" >&2 echo -e "${YELLOW}[WARN]${NC} $msg" >&2
if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then
echo "[$(timestamp)] [WARN] $msg" >> "$LOG_FILE" 2>&1 || true echo "[$(timestamp)] [WARN] $msg" >>"$LOG_FILE" 2>&1 || true
fi fi
} }
@ -56,7 +56,7 @@ error() {
local msg="$1" local msg="$1"
echo -e "${RED}[ERROR]${NC} $msg" >&2 echo -e "${RED}[ERROR]${NC} $msg" >&2
if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then if [[ -w "$(dirname "$LOG_FILE")" ]] || [[ ! -e $LOG_FILE && -w /var/log ]]; then
echo "[$(timestamp)] [ERROR] $msg" >> "$LOG_FILE" 2>&1 || true echo "[$(timestamp)] [ERROR] $msg" >>"$LOG_FILE" 2>&1 || true
fi fi
} }
@ -90,16 +90,21 @@ require_non_root() {
} }
usage() { usage() {
cat << EOF cat <<EOF
Usage: $SCRIPT_NAME [OPTIONS] [COMMAND] Usage: $SCRIPT_NAME [OPTIONS] [COMMAND]
Root BL9000 phone from Arch Linux using Magisk. Root BL9000 phone from Arch Linux using Magisk.
Commands: Commands:
install-deps Install required dependencies (adb, fastboot, tools) install-deps Install required dependencies (adb, fastboot, tools)
install-mtk Install MTKClient for MediaTek boot extraction
check Check device connection and prerequisites check Check device connection and prerequisites
backup Backup phone data before unlocking bootloader backup Backup phone data before unlocking bootloader
unlock Unlock bootloader (WARNING: wipes all data!) unlock Unlock bootloader (WARNING: wipes all data!)
extract-mtk Extract boot.img using MTKClient (for MediaTek devices)
patch Patch boot.img with Magisk (manual step on phone)
flash [IMG] Flash patched boot image (uses magisk_patched.img or specified file)
auto-root Automated: extract -> patch -> flash in one command
root Extract boot, patch with Magisk, and flash root Extract boot, patch with Magisk, and flash
full Run complete rooting process (deps + unlock + root) full Run complete rooting process (deps + unlock + root)
clean Remove temporary working directory clean Remove temporary working directory
@ -112,8 +117,11 @@ Options:
Examples: Examples:
$SCRIPT_NAME install-deps # Install required tools $SCRIPT_NAME install-deps # Install required tools
$SCRIPT_NAME install-mtk # Install MTKClient for boot extraction
$SCRIPT_NAME check # Verify device connection $SCRIPT_NAME check # Verify device connection
$SCRIPT_NAME backup # Backup phone data first! $SCRIPT_NAME backup # Backup phone data first!
$SCRIPT_NAME extract-mtk # Extract boot.img with MTKClient
$SCRIPT_NAME auto-root # Automated rooting (extract + patch + flash)
$SCRIPT_NAME full # Complete rooting process $SCRIPT_NAME full # Complete rooting process
$SCRIPT_NAME root # Root only (assumes bootloader unlocked) $SCRIPT_NAME root # Root only (assumes bootloader unlocked)
@ -130,33 +138,49 @@ install_dependencies() {
local missing=() local missing=()
# Check for required commands # Check for required commands
if ! command -v adb > /dev/null 2>&1; then if ! command -v adb >/dev/null 2>&1; then
packages+=("android-tools") packages+=("android-tools")
missing+=("adb") missing+=("adb")
fi fi
if ! command -v fastboot > /dev/null 2>&1 && ! pacman -Q android-tools > /dev/null 2>&1; then if ! command -v fastboot >/dev/null 2>&1 && ! pacman -Q android-tools >/dev/null 2>&1; then
packages+=("android-tools") packages+=("android-tools")
missing+=("fastboot") missing+=("fastboot")
fi fi
if ! command -v unzip > /dev/null 2>&1; then if ! command -v unzip >/dev/null 2>&1; then
packages+=("unzip") packages+=("unzip")
missing+=("unzip") missing+=("unzip")
fi fi
if ! command -v curl > /dev/null 2>&1; then if ! command -v curl >/dev/null 2>&1; then
packages+=("curl") packages+=("curl")
missing+=("curl") missing+=("curl")
fi fi
if ! command -v python3 > /dev/null 2>&1; then if ! command -v python3 >/dev/null 2>&1; then
packages+=("python") packages+=("python")
missing+=("python3") missing+=("python3")
fi fi
if ! command -v git >/dev/null 2>&1; then
packages+=("git")
missing+=("git")
fi
# Check for libusb and fuse2 (needed for mtkclient)
if ! pacman -Q libusb >/dev/null 2>&1; then
packages+=("libusb")
missing+=("libusb")
fi
if ! pacman -Q fuse2 >/dev/null 2>&1; then
packages+=("fuse2")
missing+=("fuse2")
fi
# Check for python-protobuf (needed for boot image tools) # Check for python-protobuf (needed for boot image tools)
if ! python3 -c "import google.protobuf" 2> /dev/null; then if ! python3 -c "import google.protobuf" 2>/dev/null; then
packages+=("python-protobuf") packages+=("python-protobuf")
missing+=("python-protobuf") missing+=("python-protobuf")
fi fi
@ -178,19 +202,6 @@ install_dependencies() {
log "Installing packages: ${packages[*]}" log "Installing packages: ${packages[*]}"
sudo pacman -S --needed --noconfirm "${packages[@]}" || die "Failed to install dependencies" sudo pacman -S --needed --noconfirm "${packages[@]}" || die "Failed to install dependencies"
# Install payload-dumper-go from AUR if not present (for extracting boot.img from payload.bin)
if ! command -v payload-dumper-go > /dev/null 2>&1; then
if confirm "Install payload-dumper-go from AUR for extracting boot images?"; then
if command -v yay > /dev/null 2>&1; then
yay -S --needed --noconfirm payload-dumper-go || warn "Failed to install payload-dumper-go (optional)"
elif command -v paru > /dev/null 2>&1; then
paru -S --needed --noconfirm payload-dumper-go || warn "Failed to install payload-dumper-go (optional)"
else
warn "No AUR helper found. Install payload-dumper-go manually if needed."
fi
fi
fi
log "Dependencies installed successfully." log "Dependencies installed successfully."
} }
@ -198,12 +209,19 @@ setup_udev_rules() {
print_header "Setting Up USB Access" print_header "Setting Up USB Access"
local udev_file="/etc/udev/rules.d/51-android.rules" local udev_file="/etc/udev/rules.d/51-android.rules"
local mtk_udev_dir="${WORK_DIR}/mtkclient/mtkclient/Setup/Linux"
# Install MTKClient udev rules if mtkclient is present
if [[ -d "${WORK_DIR}/mtkclient" ]]; then
log "Installing MTKClient udev rules..."
if [[ -d "$mtk_udev_dir" ]]; then
sudo cp "$mtk_udev_dir"/*.rules /etc/udev/rules.d/ 2>/dev/null || warn "Failed to copy MTKClient rules"
fi
fi
if [[ -f $udev_file ]]; then if [[ -f $udev_file ]]; then
log "Android udev rules already exist at $udev_file" log "Android udev rules already exist at $udev_file"
return 0 else
fi
if ! confirm "Create udev rules for Android device access?"; then if ! confirm "Create udev rules for Android device access?"; then
warn "Skipping udev rules. You may need to run commands with sudo." warn "Skipping udev rules. You may need to run commands with sudo."
return 0 return 0
@ -212,7 +230,7 @@ setup_udev_rules() {
log "Creating Android udev rules..." log "Creating Android udev rules..."
# Create comprehensive udev rules for Android devices # Create comprehensive udev rules for Android devices
sudo tee "$udev_file" > /dev/null << 'EOF' sudo tee "$udev_file" >/dev/null <<'EOF'
# Android Debug Bridge (ADB) devices # Android Debug Bridge (ADB) devices
# Add your device's vendor ID if not listed # Add your device's vendor ID if not listed
@ -223,19 +241,38 @@ SUBSYSTEM=="usb", ATTR{idVendor}=="0e8d", MODE="0666", GROUP="adbusers"
# Generic catch-all for Android devices # Generic catch-all for Android devices
SUBSYSTEM=="usb", ATTR{idVendor}=="*", ATTR{idProduct}=="*", MODE="0666", GROUP="adbusers", SYMLINK+="android%n" SUBSYSTEM=="usb", ATTR{idVendor}=="*", ATTR{idProduct}=="*", MODE="0666", GROUP="adbusers", SYMLINK+="android%n"
EOF EOF
fi
# Create adbusers group if it doesn't exist # Create adbusers group if it doesn't exist
if ! getent group adbusers > /dev/null; then if ! getent group adbusers >/dev/null; then
sudo groupadd -r adbusers sudo groupadd -r adbusers
log "Created adbusers group" log "Created adbusers group"
fi fi
# Add current user to adbusers group # Add current user to adbusers and plugdev groups
if ! groups "$USER" | grep -q '\badbusers\b'; then if ! groups "$USER" | grep -q '\badbusers\b'; then
sudo usermod -aG adbusers "$USER" sudo usermod -aG adbusers "$USER"
log "Added $USER to adbusers group" log "Added $USER to adbusers group"
fi
if ! getent group plugdev >/dev/null; then
sudo groupadd -r plugdev
fi
if ! groups "$USER" | grep -q '\bplugdev\b'; then
sudo usermod -aG plugdev "$USER"
log "Added $USER to plugdev group"
fi
if ! getent group dialout >/dev/null; then
sudo groupadd -r dialout
fi
if ! groups "$USER" | grep -q '\bdialout\b'; then
sudo usermod -aG dialout "$USER"
log "Added $USER to dialout group"
warn "You need to log out and back in for group membership to take effect." warn "You need to log out and back in for group membership to take effect."
warn "Alternatively, run: newgrp adbusers" warn "Alternatively, run: newgrp dialout"
fi fi
# Reload udev rules # Reload udev rules
@ -253,7 +290,7 @@ backup_device_data() {
mkdir -p "$backup_dir" mkdir -p "$backup_dir"
log "Backup directory: $backup_dir" # Check device connection first log "Backup directory: $backup_dir" # Check device connection first
if ! adb get-state > /dev/null 2>&1; then if ! adb get-state >/dev/null 2>&1; then
error "Device not connected. Please connect your device first." error "Device not connected. Please connect your device first."
return 1 return 1
fi fi
@ -265,7 +302,7 @@ backup_device_data() {
local storage_dirs=("DCIM" "Pictures" "Documents" "Download" "Music" "Movies" "WhatsApp" "Telegram") local storage_dirs=("DCIM" "Pictures" "Documents" "Download" "Music" "Movies" "WhatsApp" "Telegram")
for dir in "${storage_dirs[@]}"; do for dir in "${storage_dirs[@]}"; do
if adb shell "[ -d /sdcard/$dir ]" 2> /dev/null; then if adb shell "[ -d /sdcard/$dir ]" 2>/dev/null; then
log " → Backing up /sdcard/$dir..." log " → Backing up /sdcard/$dir..."
if adb pull "/sdcard/$dir" "$backup_dir/$dir" 2>&1 | grep -v "^$"; then if adb pull "/sdcard/$dir" "$backup_dir/$dir" 2>&1 | grep -v "^$"; then
log "$dir backed up successfully" log "$dir backed up successfully"
@ -277,34 +314,34 @@ backup_device_data() {
# 2. Backup SMS/MMS (if possible) # 2. Backup SMS/MMS (if possible)
log "Backing up SMS/MMS database..." log "Backing up SMS/MMS database..."
if adb shell "su -c 'cp /data/data/com.android.providers.telephony/databases/mmssms.db /sdcard/mmssms.db'" 2> /dev/null; then if adb shell "su -c 'cp /data/data/com.android.providers.telephony/databases/mmssms.db /sdcard/mmssms.db'" 2>/dev/null; then
adb pull /sdcard/mmssms.db "$backup_dir/mmssms.db" 2> /dev/null && log " ✓ SMS/MMS backed up" adb pull /sdcard/mmssms.db "$backup_dir/mmssms.db" 2>/dev/null && log " ✓ SMS/MMS backed up"
adb shell "rm /sdcard/mmssms.db" 2> /dev/null || true adb shell "rm /sdcard/mmssms.db" 2>/dev/null || true
else else
warn " ⚠ SMS/MMS backup requires root (skipping)" warn " ⚠ SMS/MMS backup requires root (skipping)"
fi fi
# 3. Backup contacts # 3. Backup contacts
log "Backing up contacts..." log "Backing up contacts..."
if adb shell "su -c 'cp /data/data/com.android.providers.contacts/databases/contacts2.db /sdcard/contacts2.db'" 2> /dev/null; then if adb shell "su -c 'cp /data/data/com.android.providers.contacts/databases/contacts2.db /sdcard/contacts2.db'" 2>/dev/null; then
adb pull /sdcard/contacts2.db "$backup_dir/contacts2.db" 2> /dev/null && log " ✓ Contacts backed up" adb pull /sdcard/contacts2.db "$backup_dir/contacts2.db" 2>/dev/null && log " ✓ Contacts backed up"
adb shell "rm /sdcard/contacts2.db" 2> /dev/null || true adb shell "rm /sdcard/contacts2.db" 2>/dev/null || true
else else
warn " ⚠ Contacts backup requires root (skipping)" warn " ⚠ Contacts backup requires root (skipping)"
fi fi
# 4. Backup call logs # 4. Backup call logs
log "Backing up call logs..." log "Backing up call logs..."
if adb shell "su -c 'cp /data/data/com.android.providers.contacts/databases/calllog.db /sdcard/calllog.db'" 2> /dev/null; then if adb shell "su -c 'cp /data/data/com.android.providers.contacts/databases/calllog.db /sdcard/calllog.db'" 2>/dev/null; then
adb pull /sdcard/calllog.db "$backup_dir/calllog.db" 2> /dev/null && log " ✓ Call logs backed up" adb pull /sdcard/calllog.db "$backup_dir/calllog.db" 2>/dev/null && log " ✓ Call logs backed up"
adb shell "rm /sdcard/calllog.db" 2> /dev/null || true adb shell "rm /sdcard/calllog.db" 2>/dev/null || true
else else
warn " ⚠ Call logs backup requires root (skipping)" warn " ⚠ Call logs backup requires root (skipping)"
fi fi
# 5. Backup app list # 5. Backup app list
log "Backing up installed apps list..." log "Backing up installed apps list..."
adb shell "pm list packages -f" > "$backup_dir/installed_apps.txt" adb shell "pm list packages -f" >"$backup_dir/installed_apps.txt"
log " ✓ App list saved to installed_apps.txt" log " ✓ App list saved to installed_apps.txt"
# 6. Backup APKs for user-installed apps (optional, can be large) # 6. Backup APKs for user-installed apps (optional, can be large)
@ -324,10 +361,10 @@ backup_device_data() {
local apk_path local apk_path
apk_path=$(adb shell "pm path $pkg" | head -n1 | sed 's/package://') apk_path=$(adb shell "pm path $pkg" | head -n1 | sed 's/package://')
if [[ -n $apk_path ]]; then if [[ -n $apk_path ]]; then
adb pull "$apk_path" "$apk_dir/${pkg}.apk" > /dev/null 2>&1 && count=$((count + 1)) adb pull "$apk_path" "$apk_dir/${pkg}.apk" >/dev/null 2>&1 && count=$((count + 1))
fi fi
fi fi
done <<< "$user_apps" done <<<"$user_apps"
log " ✓ Backed up $count APK files" log " ✓ Backed up $count APK files"
fi fi
@ -365,13 +402,13 @@ backup_device_data() {
echo echo
echo "Installed Apps:" echo "Installed Apps:"
adb shell "pm list packages -3" | sed 's/package:/ - /' adb shell "pm list packages -3" | sed 's/package:/ - /'
} > "$backup_dir/device_info.txt" } >"$backup_dir/device_info.txt"
log " ✓ Device info saved" log " ✓ Device info saved"
# Summary # Summary
local backup_size local backup_size
backup_size=$(du -sh "$backup_dir" 2> /dev/null | cut -f1 || echo "unknown") backup_size=$(du -sh "$backup_dir" 2>/dev/null | cut -f1 || echo "unknown")
echo echo
echo -e "${GREEN}╔═══════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}╔═══════════════════════════════════════════════════════╗${NC}"
@ -408,7 +445,7 @@ check_device() {
print_header "Checking Device Connection" print_header "Checking Device Connection"
log "Starting ADB server..." log "Starting ADB server..."
adb start-server > /dev/null 2>&1 || true adb start-server >/dev/null 2>&1 || true
log "Waiting for device..." log "Waiting for device..."
if ! adb wait-for-device; then if ! adb wait-for-device; then
@ -437,11 +474,11 @@ check_device() {
# Check device properties # Check device properties
local model local model
model=$(adb shell getprop ro.product.model 2> /dev/null | tr -d '\r\n' || echo "Unknown") model=$(adb shell getprop ro.product.model 2>/dev/null | tr -d '\r\n' || echo "Unknown")
log "Model: $model" log "Model: $model"
local android_version local android_version
android_version=$(adb shell getprop ro.build.version.release 2> /dev/null | tr -d '\r\n' || echo "Unknown") android_version=$(adb shell getprop ro.build.version.release 2>/dev/null | tr -d '\r\n' || echo "Unknown")
log "Android version: $android_version" log "Android version: $android_version"
local battery_level local battery_level
@ -457,7 +494,7 @@ check_device() {
# Check if bootloader is unlocked # Check if bootloader is unlocked
local unlock_status local unlock_status
unlock_status=$(adb shell getprop ro.boot.verifiedbootstate 2> /dev/null | tr -d '\r\n' || echo "unknown") unlock_status=$(adb shell getprop ro.boot.verifiedbootstate 2>/dev/null | tr -d '\r\n' || echo "unknown")
if [[ $unlock_status == "orange" || $unlock_status == "red" ]]; then if [[ $unlock_status == "orange" || $unlock_status == "red" ]]; then
log "Bootloader unlock status: ${GREEN}UNLOCKED${NC}" log "Bootloader unlock status: ${GREEN}UNLOCKED${NC}"
else else
@ -466,7 +503,7 @@ check_device() {
# Check if OEM unlocking is enabled # Check if OEM unlocking is enabled
local oem_unlock local oem_unlock
oem_unlock=$(adb shell getprop sys.oem_unlock_allowed 2> /dev/null | tr -d '\r\n' || echo "unknown") oem_unlock=$(adb shell getprop sys.oem_unlock_allowed 2>/dev/null | tr -d '\r\n' || echo "unknown")
if [[ $oem_unlock == "1" ]]; then if [[ $oem_unlock == "1" ]]; then
log "OEM unlocking: ${GREEN}ENABLED${NC}" log "OEM unlocking: ${GREEN}ENABLED${NC}"
else else
@ -592,6 +629,117 @@ download_magisk() {
return 0 return 0
} }
install_mtkclient() {
print_header "Installing MTKClient"
local mtk_dir="${WORK_DIR}/mtkclient"
if [[ -d "$mtk_dir" && -f "$mtk_dir/mtk.py" ]]; then
log "MTKClient already installed at $mtk_dir"
return 0
fi
if ! confirm "Install MTKClient for MediaTek boot image extraction?"; then
return 1
fi
log "Cloning MTKClient repository..."
if ! git clone https://github.com/bkerler/mtkclient "$mtk_dir"; then
error "Failed to clone MTKClient"
return 1
fi
log "Installing MTKClient Python dependencies..."
cd "$mtk_dir"
python3 -m pip install --user -r requirements.txt || warn "Some dependencies may have failed to install"
python3 -m pip install --user . || warn "MTKClient installation may be incomplete"
cd - >/dev/null
log "MTKClient installed successfully"
return 0
}
extract_boot_with_mtkclient() {
print_header "Extracting Boot with MTKClient"
local mtk_dir="${WORK_DIR}/mtkclient"
local boot_img="$WORK_DIR/boot.img"
local boot_a_img="$WORK_DIR/boot_a.img"
local vbmeta_a_img="$WORK_DIR/vbmeta_a.img"
if [[ ! -d "$mtk_dir" ]]; then
error "MTKClient not installed. Run: $SCRIPT_NAME install-mtk"
return 1
fi
echo
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " MTKClient Boot ROM Mode Instructions"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo
echo "BEFORE continuing, you MUST:"
echo
echo " 1. Power off your phone COMPLETELY"
echo " 2. DISCONNECT the USB cable from your phone"
echo " 3. Have the USB cable ready in your hand"
echo
echo "When you press Enter:"
echo
echo " 4. Press and hold BOTH Volume buttons (Up + Down)"
echo " 5. While holding BOTH buttons, connect USB cable"
echo " 6. Keep holding until device is detected (may take 5-10 seconds)"
echo
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo
if ! confirm "Phone is OFF and USB DISCONNECTED - ready to proceed?"; then
return 1
fi
log "Starting MTKClient NOW - quickly enter BROM mode!"
log "Hold BOTH volume buttons and connect USB cable..."
echo
cd "$mtk_dir"
# Activate venv and extract boot and vbmeta
if [[ ! -d "$mtk_dir/venv" ]]; then
error "MTKClient virtual environment not found. Run: $SCRIPT_NAME install-mtk"
cd - >/dev/null
return 1
fi
# shellcheck source=/dev/null
source venv/bin/activate
# BL9000 uses A/B partitions, so extract boot_a and vbmeta_a
if python3 mtk.py r boot_a,vbmeta_a "$boot_a_img,$vbmeta_a_img"; then
log "Boot_a and vbmeta_a extracted successfully!"
# Copy boot_a.img to boot.img for Magisk compatibility
cp "$boot_a_img" "$boot_img"
BOOT_IMG="$boot_img"
log "Boot image ready for patching: $BOOT_IMG"
# Reset device
log "Resetting device..."
python3 mtk.py reset || warn "Failed to reset device, please reboot manually"
# Deactivate venv if function exists
type deactivate &>/dev/null && deactivate
cd - >/dev/null
return 0
else
# Deactivate venv if function exists
type deactivate &>/dev/null && deactivate
error "Failed to extract boot image with MTKClient"
cd - >/dev/null
return 1
fi
}
extract_boot_image() { extract_boot_image() {
print_header "Extracting Boot Image" print_header "Extracting Boot Image"
@ -606,27 +754,36 @@ extract_boot_image() {
log "Attempting to extract boot image from device..." log "Attempting to extract boot image from device..."
# Method 1: Try to pull boot partition directly # Method 1: Try MTKClient first (best for MediaTek devices)
if [[ -d "${WORK_DIR}/mtkclient" ]]; then
log "Trying MTKClient extraction..."
if extract_boot_with_mtkclient; then
return 0
fi
warn "MTKClient extraction failed, trying ADB methods..."
fi
# Method 2: Try to pull boot partition directly via ADB
local boot_partition local boot_partition
boot_partition=$(adb shell "find /dev/block -name boot | head -n1" 2> /dev/null | tr -d '\r\n' || echo "") boot_partition=$(adb shell "find /dev/block -name boot | head -n1" 2>/dev/null | tr -d '\r\n' || echo "")
if [[ -n $boot_partition ]]; then if [[ -n $boot_partition ]]; then
log "Found boot partition: $boot_partition" log "Found boot partition: $boot_partition"
if adb pull "$boot_partition" "$boot_img" 2> /dev/null; then if adb pull "$boot_partition" "$boot_img" 2>/dev/null; then
log "Boot image extracted successfully" log "Boot image extracted successfully"
BOOT_IMG="$boot_img" BOOT_IMG="$boot_img"
return 0 return 0
fi fi
fi fi
# Method 2: Try to get boot partition via by-name # Method 3: Try to get boot partition via by-name
boot_partition=$(adb shell "ls /dev/block/by-name/boot*" 2> /dev/null | head -n1 | tr -d '\r\n' || echo "") boot_partition=$(adb shell "ls /dev/block/by-name/boot*" 2>/dev/null | head -n1 | tr -d '\r\n' || echo "")
if [[ -n $boot_partition ]]; then if [[ -n $boot_partition ]]; then
log "Found boot partition: $boot_partition" log "Found boot partition: $boot_partition"
if adb shell "su -c 'dd if=$boot_partition of=/sdcard/boot.img'" 2> /dev/null && if adb shell "su -c 'dd if=$boot_partition of=/sdcard/boot.img'" 2>/dev/null &&
adb pull /sdcard/boot.img "$boot_img" 2> /dev/null; then adb pull /sdcard/boot.img "$boot_img" 2>/dev/null; then
adb shell rm /sdcard/boot.img 2> /dev/null || true adb shell rm /sdcard/boot.img 2>/dev/null || true
log "Boot image extracted successfully" log "Boot image extracted successfully"
BOOT_IMG="$boot_img" BOOT_IMG="$boot_img"
return 0 return 0
@ -636,8 +793,8 @@ extract_boot_image() {
error "Failed to extract boot image automatically." error "Failed to extract boot image automatically."
echo echo
echo "Manual extraction options:" echo "Manual extraction options:"
echo "1. Extract boot.img from your device's firmware package" echo "1. Use MTKClient: $SCRIPT_NAME extract-mtk"
echo "2. Use MTK Droid Tools (for MediaTek devices)" echo "2. Extract boot.img from your device's firmware package"
echo "3. Get boot.img from device manufacturer's official ROM" echo "3. Get boot.img from device manufacturer's official ROM"
echo echo
echo "Then run: $SCRIPT_NAME root --boot-img /path/to/boot.img" echo "Then run: $SCRIPT_NAME root --boot-img /path/to/boot.img"
@ -658,10 +815,14 @@ patch_boot_with_magisk() {
die "Magisk APK not found. Run download step first." die "Magisk APK not found. Run download step first."
fi fi
log "Checking if device is connected..."
if ! adb devices | grep -q "device$"; then
die "No device detected. Make sure USB debugging is enabled and device is connected."
fi
log "Installing Magisk APK on device..." log "Installing Magisk APK on device..."
if ! adb install -r "$magisk_apk" 2> /dev/null; then if ! adb install -r "$magisk_apk" 2>/dev/null; then
error "Failed to install Magisk APK" warn "Magisk APK installation failed (may already be installed)"
return 1
fi fi
log "Pushing boot image to device..." log "Pushing boot image to device..."
@ -718,6 +879,7 @@ flash_patched_boot() {
echo echo
echo -e "${YELLOW}This will flash the patched boot image to your device.${NC}" echo -e "${YELLOW}This will flash the patched boot image to your device.${NC}"
echo "Device uses A/B partitions - will flash to boot_a"
echo echo
if ! confirm "Proceed with flashing?"; then if ! confirm "Proceed with flashing?"; then
@ -731,19 +893,19 @@ flash_patched_boot() {
log "Waiting for fastboot mode..." log "Waiting for fastboot mode..."
sleep 5 sleep 5
if ! fastboot devices | grep -q .; then if ! sudo fastboot devices | grep -q .; then
die "Device not detected in fastboot mode" die "Device not detected in fastboot mode"
fi fi
log "Flashing patched boot image..." log "Flashing patched boot image to boot_a..."
if ! fastboot flash boot "$PATCHED_BOOT_IMG"; then if ! sudo fastboot flash boot_a "$PATCHED_BOOT_IMG"; then
error "Failed to flash boot image" error "Failed to flash boot image"
return 1 return 1
fi fi
log "Flashed successfully!" log "Flashed successfully!"
log "Rebooting device..." log "Rebooting device..."
fastboot reboot sudo fastboot reboot
log "Waiting for device to boot..." log "Waiting for device to boot..."
sleep 10 sleep 10
@ -845,6 +1007,15 @@ main() {
local command="${1:-help}" local command="${1:-help}"
shift || true shift || true
# Handle flash command's image argument before option parsing
if [[ $command == "flash" && -n ${1:-} && $1 != --* ]]; then
PATCHED_BOOT_IMG="$1"
if [[ ! -f $PATCHED_BOOT_IMG ]]; then
die "Patched boot image file not found: $PATCHED_BOOT_IMG"
fi
shift
fi
# Parse options # Parse options
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
@ -877,6 +1048,11 @@ main() {
install_dependencies install_dependencies
setup_udev_rules setup_udev_rules
;; ;;
install-mtk)
install_dependencies
setup_udev_rules
install_mtkclient
;;
check) check)
check_device check_device
;; ;;
@ -888,6 +1064,35 @@ main() {
check_device || die "Device check failed" check_device || die "Device check failed"
unlock_bootloader unlock_bootloader
;; ;;
extract-mtk)
extract_boot_with_mtkclient
;;
patch)
# Patch the extracted boot image with Magisk
if [[ -f "$WORK_DIR/boot.img" ]]; then
BOOT_IMG="$WORK_DIR/boot.img"
fi
patch_boot_with_magisk
;;
flash)
# Flash the patched boot image
if [[ -z ${PATCHED_BOOT_IMG:-} ]]; then
if [[ -f "$WORK_DIR/magisk_patched.img" ]]; then
PATCHED_BOOT_IMG="$WORK_DIR/magisk_patched.img"
else
die "No patched boot image specified and none found at $WORK_DIR/magisk_patched.img"
fi
fi
flash_patched_boot
;;
auto-root)
# Automated rooting: extract -> patch -> flash
extract_boot_with_mtkclient || die "Boot extraction failed"
BOOT_IMG="$WORK_DIR/boot.img"
patch_boot_with_magisk || die "Boot patching failed"
flash_patched_boot || die "Boot flashing failed"
log "Rooting process completed!"
;;
root) root)
run_root_only run_root_only
;; ;;

View File

@ -0,0 +1,217 @@
#!/bin/bash
set -euo pipefail
# Re-run with sudo if needed for reading /etc/hosts
if [[ $EUID -ne 0 ]] && [[ ! -r /etc/hosts ]]; then
exec sudo -E bash "$0" "$@"
fi
WORK_DIR="${HOME}/.cache/android-adblock"
mkdir -p "$WORK_DIR"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S%z')]${NC} $*"
}
error() {
echo -e "${RED}[ERROR]${NC} $*" >&2
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $*"
}
die() {
error "$@"
exit 1
}
print_header() {
echo
echo "========================================"
echo " $1"
echo "========================================"
echo
}
check_device() {
log "Checking device connection..."
if ! adb devices | grep -q "device$"; then
die "No device connected. Enable USB debugging and connect your phone."
fi
log "Device connected"
}
check_root() {
log "Checking root access..."
if ! adb shell "su -c 'echo test'" 2>/dev/null | grep -q "test"; then
die "Root access not available. Make sure Magisk is installed and grant root to Shell."
fi
log "Root access confirmed"
}
install_adaway() {
print_header "Installing AdAway"
local adaway_apk="$WORK_DIR/adaway.apk"
local adaway_url="https://github.com/AdAway/AdAway/releases/latest/download/AdAway.apk"
if [[ ! -f $adaway_apk ]]; then
log "Downloading AdAway APK..."
curl -L -o "$adaway_apk" "$adaway_url" || die "Failed to download AdAway"
else
log "AdAway APK already downloaded"
fi
log "Installing AdAway..."
if adb install -r "$adaway_apk" 2>&1 | grep -q "Success"; then
log "AdAway installed successfully"
else
warn "AdAway installation may have failed or already installed"
fi
}
setup_systemless_hosts() {
print_header "Setting up Systemless Hosts"
log "Installing Systemless Hosts module..."
# Create systemless hosts module directory
adb shell "su -c 'mkdir -p /data/adb/modules/systemless_hosts/system/etc'" || die "Failed to create module directory"
# Create module.prop
cat >"$WORK_DIR/module.prop" <<'EOF'
id=systemless_hosts
name=Systemless Hosts
version=1.0
versionCode=1
author=Custom
description=Custom hosts file from StevenBlack with extensions
EOF
adb push "$WORK_DIR/module.prop" /sdcard/module.prop
adb shell "su -c 'cp /sdcard/module.prop /data/adb/modules/systemless_hosts/'" || die "Failed to create module.prop"
adb shell "su -c 'rm /sdcard/module.prop'"
log "Module structure created"
}
push_hosts_file() {
print_header "Pushing Custom Hosts File"
local hosts_file="$WORK_DIR/hosts"
# Use the StevenBlack cache or generate from /etc/hosts
if [[ -f /etc/hosts.stevenblack ]]; then
log "Using StevenBlack hosts cache..."
cp /etc/hosts.stevenblack "$hosts_file"
elif [[ -f /etc/hosts ]]; then
log "Using current /etc/hosts..."
cp /etc/hosts "$hosts_file"
else
die "No hosts file found"
fi
# Show stats
local total_entries
total_entries=$(grep -c "^0\.0\.0\.0 " "$hosts_file" || echo 0)
log "Hosts file contains $total_entries blocked domains"
log "Pushing hosts file to device..."
adb push "$hosts_file" /sdcard/hosts || die "Failed to push hosts file"
log "Installing hosts file systemlessly..."
adb shell "su -c 'cp /sdcard/hosts /data/adb/modules/systemless_hosts/system/etc/hosts'" || die "Failed to install hosts file"
adb shell "su -c 'chmod 644 /data/adb/modules/systemless_hosts/system/etc/hosts'" || die "Failed to set permissions"
adb shell "su -c 'rm /sdcard/hosts'"
log "Hosts file installed successfully"
log "Total blocked domains: $total_entries"
}
enable_module() {
print_header "Enabling Systemless Hosts Module"
log "Removing disable flag if present..."
adb shell "su -c 'rm -f /data/adb/modules/systemless_hosts/disable'" 2>/dev/null || true
adb shell "su -c 'rm -f /data/adb/modules/systemless_hosts/remove'" 2>/dev/null || true
log "Module enabled"
echo
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " REBOOT REQUIRED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo
echo "The systemless hosts module requires a reboot to take effect."
echo
read -p "Reboot device now? [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log "Rebooting device..."
adb reboot
log "Device rebooting. Wait for boot to complete."
else
warn "Remember to reboot manually for changes to take effect!"
fi
}
verify_hosts() {
print_header "Verifying Hosts Installation"
log "Waiting for device to boot..."
sleep 5
adb wait-for-device
sleep 10
log "Checking if hosts file is active..."
local test_domain="doubleclick.net"
local result
result=$(adb shell "su -c 'cat /system/etc/hosts | grep -c $test_domain'" 2>/dev/null || echo "0")
if [[ $result -gt 0 ]]; then
log "✓ Hosts file is active and blocking domains"
else
warn "Could not verify hosts file, but module should be installed"
fi
}
main() {
print_header "Android Ad Blocking Setup"
check_device
check_root
echo "This will:"
echo " 1. Install AdAway app (optional GUI management)"
echo " 2. Create systemless hosts module"
echo " 3. Push your custom hosts file (StevenBlack with extensions)"
echo " 4. Enable the module and reboot"
echo
read -p "Continue? [y/N]: " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log "Cancelled by user"
exit 0
fi
install_adaway
setup_systemless_hosts
push_hosts_file
enable_module
log "Setup complete!"
log "After reboot, ads should be blocked system-wide"
log "You can manage hosts in the AdAway app or by updating the module"
}
main "$@"

View File

@ -0,0 +1,208 @@
#!/bin/bash
set -euo pipefail
# Re-run with sudo if needed for reading /etc/hosts
if [[ $EUID -ne 0 ]] && [[ ! -r /etc/hosts ]]; then
exec sudo -E bash "$0" "$@"
fi
WORK_DIR="${HOME}/.cache/android-adblock"
mkdir -p "$WORK_DIR"
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S%z')]${NC} $*"
}
error() {
echo -e "${RED}[ERROR]${NC} $*" >&2
}
die() {
error "$@"
exit 1
}
log "Updating Android hosts file from Linux configuration..."
# Check device connection
if ! adb devices | grep -q "device$"; then
die "No device connected. Enable USB debugging and connect your phone."
fi
# Check root access
if ! adb shell "su -c 'echo test'" 2>/dev/null | grep -q "test"; then
die "Root access not available. Make sure Magisk is installed and grant root to Shell."
fi
# Use the StevenBlack cache or /etc/hosts
HOSTS_FILE="$WORK_DIR/hosts"
if [[ -f /etc/hosts.stevenblack ]]; then
log "Using StevenBlack hosts cache..."
cp /etc/hosts.stevenblack "$HOSTS_FILE"
elif [[ -f /etc/hosts ]]; then
log "Using /etc/hosts..."
cp /etc/hosts "$HOSTS_FILE"
else
die "No hosts file found"
fi
# Show stats
TOTAL_ENTRIES=$(grep -c "^0\.0\.0\.0 " "$HOSTS_FILE" || echo 0)
log "Hosts file contains $TOTAL_ENTRIES blocked domains"
# Push to device
log "Pushing hosts file to device..."
adb push "$HOSTS_FILE" /sdcard/hosts || die "Failed to push hosts file"
# Install systemlessly
log "Updating systemless hosts..."
adb shell "su -c 'mkdir -p /data/adb/modules/systemless_hosts/system/etc'" || die "Failed to create module directory"
adb shell "su -c 'cp /sdcard/hosts /data/adb/modules/systemless_hosts/system/etc/hosts'" || die "Failed to install hosts file"
adb shell "su -c 'chmod 644 /data/adb/modules/systemless_hosts/system/etc/hosts'" || die "Failed to set permissions"
adb shell "su -c 'rm /sdcard/hosts'"
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] ✓ Hosts file updated successfully"
# Append custom blocking entries
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] Adding custom blocking entries..."
adb shell "su -c 'cat >> /data/adb/modules/systemless_hosts/system/etc/hosts << \"CUSTOM_EOF\"
# Custom blocking entries
# YouTube
0.0.0.0 youtube.com
0.0.0.0 www.youtube.com
0.0.0.0 m.youtube.com
0.0.0.0 youtu.be
0.0.0.0 youtube-nocookie.com
0.0.0.0 www.youtube-nocookie.com
0.0.0.0 youtubei.googleapis.com
0.0.0.0 youtube.googleapis.com
0.0.0.0 yt3.ggpht.com
0.0.0.0 ytimg.com
0.0.0.0 i.ytimg.com
0.0.0.0 s.ytimg.com
0.0.0.0 i9.ytimg.com
0.0.0.0 googlevideo.com
0.0.0.0 r1---sn-4g5e6nls.googlevideo.com
0.0.0.0 r1---sn-4g5lne7s.googlevideo.com
# Steam Store
# Discord (selective blocking - media only, voice chat allowed)
0.0.0.0 cdn.discordapp.com
0.0.0.0 media.discordapp.net
0.0.0.0 images-ext-1.discordapp.net
0.0.0.0 images-ext-2.discordapp.net
0.0.0.0 attachments-1.discordapp.net
0.0.0.0 attachments-2.discordapp.net
0.0.0.0 tenor.com
0.0.0.0 giphy.com
# Food Delivery Services
# Polish services
0.0.0.0 pyszne.pl
0.0.0.0 www.pyszne.pl
0.0.0.0 m.pyszne.pl
0.0.0.0 glovo.com
0.0.0.0 www.glovo.com
0.0.0.0 m.glovo.com
0.0.0.0 bolt.eu
0.0.0.0 food.bolt.eu
0.0.0.0 woltwojta.pl
0.0.0.0 www.woltwojta.pl
0.0.0.0 wolt.com
0.0.0.0 www.wolt.com
0.0.0.0 m.wolt.com
# International services
0.0.0.0 ubereats.com
0.0.0.0 www.ubereats.com
0.0.0.0 m.ubereats.com
0.0.0.0 uber.com
0.0.0.0 www.uber.com
0.0.0.0 m.uber.com
0.0.0.0 deliveroo.com
0.0.0.0 www.deliveroo.com
0.0.0.0 m.deliveroo.com
0.0.0.0 deliveroo.co.uk
0.0.0.0 www.deliveroo.co.uk
0.0.0.0 foodpanda.com
0.0.0.0 www.foodpanda.com
0.0.0.0 m.foodpanda.com
0.0.0.0 grubhub.com
0.0.0.0 www.grubhub.com
0.0.0.0 m.grubhub.com
0.0.0.0 doordash.com
0.0.0.0 www.doordash.com
0.0.0.0 m.doordash.com
0.0.0.0 justeat.com
0.0.0.0 www.justeat.com
0.0.0.0 m.justeat.com
0.0.0.0 justeat.co.uk
0.0.0.0 www.justeat.co.uk
0.0.0.0 postmates.com
0.0.0.0 www.postmates.com
0.0.0.0 seamless.com
0.0.0.0 www.seamless.com
0.0.0.0 menulog.com.au
0.0.0.0 www.menulog.com.au
0.0.0.0 delivery.com
0.0.0.0 www.delivery.com
# Fast food chain apps and websites
0.0.0.0 mcdonalds.com
0.0.0.0 www.mcdonalds.com
0.0.0.0 m.mcdonalds.com
0.0.0.0 mcdonalds.pl
0.0.0.0 www.mcdonalds.pl
0.0.0.0 kfc.com
0.0.0.0 www.kfc.com
0.0.0.0 m.kfc.com
0.0.0.0 kfc.pl
0.0.0.0 www.kfc.pl
0.0.0.0 burgerking.com
0.0.0.0 www.burgerking.com
0.0.0.0 m.burgerking.com
0.0.0.0 burgerking.pl
0.0.0.0 www.burgerking.pl
0.0.0.0 pizzahut.com
0.0.0.0 www.pizzahut.com
0.0.0.0 m.pizzahut.com
0.0.0.0 pizzahut.pl
0.0.0.0 www.pizzahut.pl
0.0.0.0 dominos.com
0.0.0.0 www.dominos.com
0.0.0.0 m.dominos.com
0.0.0.0 dominos.pl
0.0.0.0 www.dominos.pl
0.0.0.0 subway.com
0.0.0.0 www.subway.com
0.0.0.0 m.subway.com
0.0.0.0 subway.pl
0.0.0.0 www.subway.pl
CUSTOM_EOF
'" || {
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] ✗ Failed to add custom entries"
exit 1
}
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] ✓ Custom entries added successfully"
# Count and display blocked domains
domain_count=$(adb shell "su -c 'cat /system/etc/hosts | grep -c \"^0.0.0.0\"'" 2>/dev/null | tr -d '\r')
if [[ -n $domain_count ]]; then
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] ✓ Total blocked domains: $domain_count"
fi
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] ✓ Changes will take effect immediately for new connections"
echo "[$(date +'%Y-%m-%d %H:%M:%S%z')] (Optional: Toggle airplane mode or reboot to force all apps to reconnect)"
log "✓ Total blocked domains: $TOTAL_ENTRIES"
log ""
log "Changes will take effect immediately for new connections."
log "To apply to all apps, reboot the device or toggle airplane mode."